qmlmathplot 0.4.3__py3-none-any.whl → 0.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qmlmathplot/model.py +103 -5
- {qmlmathplot-0.4.3.dist-info → qmlmathplot-0.4.4.dist-info}/METADATA +1 -1
- {qmlmathplot-0.4.3.dist-info → qmlmathplot-0.4.4.dist-info}/RECORD +5 -5
- {qmlmathplot-0.4.3.dist-info → qmlmathplot-0.4.4.dist-info}/WHEEL +1 -1
- {qmlmathplot-0.4.3.dist-info → qmlmathplot-0.4.4.dist-info}/entry_points.txt +0 -0
qmlmathplot/model.py
CHANGED
|
@@ -358,6 +358,12 @@ float _seg_dist(vec2 p, vec2 a, vec2 b) {
|
|
|
358
358
|
return length(p - (a + t * ab));
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
+
// A vertical interval [lo, hi] at this pixel's y, with a one-pixel feather at its edges.
|
|
362
|
+
float _span_cov(float y, float lo, float hi, float sy) {
|
|
363
|
+
return clamp((y - lo) * sy + 1.0, 0.0, 1.0)
|
|
364
|
+
* clamp((hi - y) * sy + 1.0, 0.0, 1.0);
|
|
365
|
+
}
|
|
366
|
+
|
|
361
367
|
// GLSL pow() is undefined for a negative base; odd roots are real there (x**(1/3)).
|
|
362
368
|
float _real_pow(float v, float p) {
|
|
363
369
|
return v < 0.0 ? -pow(-v, p) : pow(v, p);
|
|
@@ -471,6 +477,11 @@ void main() {
|
|
|
471
477
|
}
|
|
472
478
|
}
|
|
473
479
|
|
|
480
|
+
// A pole inside this column is a jump, even when a monotone map such as exp()
|
|
481
|
+
// turns the two one-sided limits into a connected range (exp(tan(x)): 0 and +inf).
|
|
482
|
+
// The interval paths below would bridge that jump with a vertical connector.
|
|
483
|
+
bool pole_col = HAS_SIGN_POLE && POLE(x - 0.5 * dx) * POLE(x + 0.5 * dx) <= 0.0;
|
|
484
|
+
|
|
474
485
|
// ---- fixed-x sub-pixel polyline (GeoGebra's sampled polyline, on the GPU) ----
|
|
475
486
|
// 14 samples over ±2 columns (0.286-column spacing) cover the perpendicular foot even at
|
|
476
487
|
// 89°: a ±1-column window lost 42 % of the width at 84°. Joining the samples gives a
|
|
@@ -488,9 +499,28 @@ void main() {
|
|
|
488
499
|
bool prev_ok = false;
|
|
489
500
|
float prev_d = 0.0;
|
|
490
501
|
bool prev_d_ok = false;
|
|
502
|
+
int pole_crossings = 0;
|
|
503
|
+
#if HAS_SIGN_POLE
|
|
504
|
+
if (abs(camera.z) > 1.0) {
|
|
505
|
+
float pp = POLE(x - 2.0 * dx);
|
|
506
|
+
for (int pi = 0; pi < 32; pi++) {
|
|
507
|
+
float tt = -2.0 + 4.0 * fract((float(pi) + 0.5) * 0.61803398875);
|
|
508
|
+
float px = x + tt * dx;
|
|
509
|
+
float pv = POLE(px);
|
|
510
|
+
if (pp * pv <= 0.0) pole_crossings += 1;
|
|
511
|
+
pp = pv;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
#endif
|
|
515
|
+
float prev_pole = 1.0;
|
|
491
516
|
for (int i = 0; i < NS; i++) {
|
|
492
517
|
float t = -2.0 + (float(i) + 0.5) * (4.0 / float(NS));
|
|
493
518
|
float xi = x + t * dx;
|
|
519
|
+
float pv = POLE(xi);
|
|
520
|
+
if (i > 0 && prev_pole * pv <= 0.0) {
|
|
521
|
+
pole_crossings += 1;
|
|
522
|
+
}
|
|
523
|
+
prev_pole = pv;
|
|
494
524
|
float v = 1e30;
|
|
495
525
|
if (DOMS(xi)) {
|
|
496
526
|
v = F(xi);
|
|
@@ -527,14 +557,61 @@ void main() {
|
|
|
527
557
|
}
|
|
528
558
|
}
|
|
529
559
|
|
|
560
|
+
// A single column path, as GeoGebra's IntervalPath: every resolvable connected column
|
|
561
|
+
// contributes one chord from its left-edge value to its right-edge value. The sampled
|
|
562
|
+
// polyline is only a fallback for columns where the interval cannot be oriented.
|
|
563
|
+
bool use_path = col.kind == IK_CONNECTED && col.lo > -IINF && col.hi < IINF
|
|
564
|
+
&& !pole_col && !HAS_DEPENDENT_QUOTIENT && sturns < 1.5;
|
|
565
|
+
bool inc = true;
|
|
566
|
+
if (use_path) {
|
|
567
|
+
int fi = -1;
|
|
568
|
+
int li = -1;
|
|
569
|
+
for (int i = 0; i < NS; i++) {
|
|
570
|
+
if (ok[i]) {
|
|
571
|
+
if (fi < 0) fi = i;
|
|
572
|
+
li = i;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (fi >= 0 && li > fi && smp[li] < smp[fi]) {
|
|
576
|
+
inc = false;
|
|
577
|
+
}
|
|
578
|
+
float y0 = inc ? col.lo : col.hi;
|
|
579
|
+
float y1 = inc ? col.hi : col.lo;
|
|
580
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
581
|
+
vec2((x - 0.5 * dx) * sx, y0 * sy),
|
|
582
|
+
vec2((x + 0.5 * dx) * sx, y1 * sy)));
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Neighbour joins: the chord above ends at this column's edges; the previous/next
|
|
586
|
+
// columns' chords end at the same boundary but from their own interval. A short
|
|
587
|
+
// boundary join removes the 1-px gap/step at the hand-off.
|
|
588
|
+
if (use_path && (col.hi - col.lo) * sy > 2.0 * R) {
|
|
589
|
+
IVal prevc = FI(x - 1.5 * dx, x - 0.5 * dx);
|
|
590
|
+
IVal nextc = FI(x + 0.5 * dx, x + 1.5 * dx);
|
|
591
|
+
if (prevc.kind == IK_CONNECTED && prevc.lo > -IINF && prevc.hi < IINF) {
|
|
592
|
+
float left = inc ? prevc.hi : prevc.lo;
|
|
593
|
+
float here = inc ? col.lo : col.hi;
|
|
594
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
595
|
+
vec2((x - 0.5 * dx) * sx, left * sy),
|
|
596
|
+
vec2((x - 0.5 * dx) * sx, here * sy)));
|
|
597
|
+
}
|
|
598
|
+
if (nextc.kind == IK_CONNECTED && nextc.lo > -IINF && nextc.hi < IINF) {
|
|
599
|
+
float here = inc ? col.hi : col.lo;
|
|
600
|
+
float right = inc ? nextc.lo : nextc.hi;
|
|
601
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
602
|
+
vec2((x + 0.5 * dx) * sx, here * sy),
|
|
603
|
+
vec2((x + 0.5 * dx) * sx, right * sy)));
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
530
607
|
// GeoGebra's unbounded-column rule (IntervalPath.drawNormalInfinity): only when the
|
|
531
608
|
// finite bound itself is on screen. The segment uses the column's left edge and middle.
|
|
532
|
-
if (col.kind == IK_CONNECTED && col.lo <= -IINF
|
|
609
|
+
if (!pole_col && col.kind == IK_CONNECTED && col.lo <= -IINF
|
|
533
610
|
&& col.hi >= y_bot && col.hi <= y_top) {
|
|
534
611
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
535
612
|
vec2((x - 0.5 * dx) * sx, col.hi * sy), vec2(x * sx, y_bot * sy)));
|
|
536
613
|
}
|
|
537
|
-
if (col.kind == IK_CONNECTED && col.hi >= IINF
|
|
614
|
+
if (!pole_col && col.kind == IK_CONNECTED && col.hi >= IINF
|
|
538
615
|
&& col.lo >= y_bot && col.lo <= y_top) {
|
|
539
616
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
540
617
|
vec2((x - 0.5 * dx) * sx, col.lo * sy), vec2(x * sx, y_top * sy)));
|
|
@@ -543,11 +620,11 @@ void main() {
|
|
|
543
620
|
// covers it (the visible curve lies inside this x column). GeoGebra's normal-infinity
|
|
544
621
|
// branch declines to draw here; the column is effectively whole (drawWhole), so a
|
|
545
622
|
// vertical segment at the left edge is GGB's own rule for that topology.
|
|
546
|
-
if (col.kind == IK_CONNECTED && col.lo <= -IINF && col.hi > y_top) {
|
|
623
|
+
if (!pole_col && col.kind == IK_CONNECTED && col.lo <= -IINF && col.hi > y_top) {
|
|
547
624
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
548
625
|
vec2((x - 0.5 * dx) * sx, y_bot * sy), vec2((x - 0.5 * dx) * sx, y_top * sy)));
|
|
549
626
|
}
|
|
550
|
-
if (col.kind == IK_CONNECTED && col.hi >= IINF && col.lo < y_bot) {
|
|
627
|
+
if (!pole_col && col.kind == IK_CONNECTED && col.hi >= IINF && col.lo < y_bot) {
|
|
551
628
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
552
629
|
vec2((x - 0.5 * dx) * sx, y_bot * sy), vec2((x - 0.5 * dx) * sx, y_top * sy)));
|
|
553
630
|
}
|
|
@@ -561,11 +638,15 @@ void main() {
|
|
|
561
638
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
562
639
|
vec2((x + 0.5 * dx) * sx, y_top * sy),
|
|
563
640
|
vec2((x + 0.5 * dx) * sx, col.hi * sy)));
|
|
641
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
642
|
+
vec2(x * sx, y_top * sy), vec2(x * sx, col.hi * sy)));
|
|
564
643
|
}
|
|
565
644
|
if (col.hi > y_bot) {
|
|
566
645
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
567
646
|
vec2((x - 0.5 * dx) * sx, y_bot * sy),
|
|
568
647
|
vec2((x - 0.5 * dx) * sx, col.lo * sy)));
|
|
648
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
649
|
+
vec2(x * sx, y_bot * sy), vec2(x * sx, col.lo * sy)));
|
|
569
650
|
}
|
|
570
651
|
}
|
|
571
652
|
|
|
@@ -573,6 +654,8 @@ void main() {
|
|
|
573
654
|
if (col.kind == IK_WHOLE && FILL_WHOLE) {
|
|
574
655
|
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
575
656
|
vec2((x - 0.5 * dx) * sx, y_bot * sy), vec2((x - 0.5 * dx) * sx, y_top * sy)));
|
|
657
|
+
pmin = min(pmin, _seg_dist(vec2(x * sx, y * sy),
|
|
658
|
+
vec2(x * sx, y_bot * sy), vec2(x * sx, y_top * sy)));
|
|
576
659
|
}
|
|
577
660
|
|
|
578
661
|
float band_cov = 0.0;
|
|
@@ -612,7 +695,22 @@ void main() {
|
|
|
612
695
|
if (HAS_DEPENDENT_QUOTIENT && !FILL_WHOLE) {
|
|
613
696
|
band_cov = 0.0; // dependency overestimation: the polyline draws the real branches
|
|
614
697
|
}
|
|
615
|
-
float
|
|
698
|
+
float dense = 0.0;
|
|
699
|
+
if (HAS_SIGN_POLE && pole_crossings >= 1 && abs(camera.z) > 1.0
|
|
700
|
+
&& col.kind != IK_EMPTY) {
|
|
701
|
+
// Several poles inside the sampling window: the column is undersampled, so fill its
|
|
702
|
+
// *attained* y interval instead of drawing one branch per sample. Inverted means the
|
|
703
|
+
// gap [lo, hi] is not attained; filling it would paint the asymptote.
|
|
704
|
+
if (col.kind == IK_WHOLE) {
|
|
705
|
+
dense = 1.0;
|
|
706
|
+
} else if (col.kind == IK_INVERTED) {
|
|
707
|
+
dense = max(_span_cov(y, y_bot, col.lo, sy),
|
|
708
|
+
_span_cov(y, col.hi, y_top, sy));
|
|
709
|
+
} else {
|
|
710
|
+
dense = _span_cov(y, max(col.lo, y_bot), min(col.hi, y_top), sy);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
float cov = max(max(band_cov, dense), clamp(R - pmin, 0.0, 1.0));
|
|
616
714
|
if (!DOM(x)) {
|
|
617
715
|
float a = cov * color.a * qt_Opacity;
|
|
618
716
|
fragColor = vec4(color.rgb * a, a);
|
|
@@ -9,7 +9,7 @@ qmlmathplot/export.py,sha256=KmWhh87rHOcdWfHo0erRvPgva_xm_RK8Uxf5HCbTv30,9276
|
|
|
9
9
|
qmlmathplot/figure.py,sha256=iuCIuRExdcq36lDj-BA6QSsh2STeBLbgCVbvU7q_c2Y,20777
|
|
10
10
|
qmlmathplot/input.py,sha256=Mb1rL-_Zynl1K-mhKEjjCv_BOA31cHekpL79eMdWUw0,6036
|
|
11
11
|
qmlmathplot/interval.py,sha256=MoWEE6piNPr5cqGNf7nHKXu4RioROJg6qyBvtydhyyQ,21362
|
|
12
|
-
qmlmathplot/model.py,sha256=
|
|
12
|
+
qmlmathplot/model.py,sha256=zX73YzjATEcEtaKMeCd7NJQub3rkP1VCoB2JChFvezI,77179
|
|
13
13
|
qmlmathplot/mpl.py,sha256=4xjKTwzv9liTaRCsKGNG-lmvRtrBHOv8vBJGfkAZ41o,13358
|
|
14
14
|
qmlmathplot/overlay.py,sha256=QY-daroe7Nrs8F5t7XcFR82xfRDstZDHq9JDFfPehYs,13171
|
|
15
15
|
qmlmathplot/plot.py,sha256=MstIKlXFCvnALxFYVZBBr8LWfuU9D-iS33P5e3W66d0,25851
|
|
@@ -53,7 +53,7 @@ qmlmathplot/themes/tableau-colorblind10.mplstyle,sha256=PzUMoOtw0V6l0bPk8ApRAKvc
|
|
|
53
53
|
qmlmathplot/themes.py,sha256=QocZLOgPYXCJW9fYc6i5q6nHEE_S4mQVZXySZ4ISCPw,9225
|
|
54
54
|
qmlmathplot/view.py,sha256=cQVzX7WdFXdAGjNu0LzZMzgFfCmLwfBsUMZFQrsWFy8,1775
|
|
55
55
|
qmlmathplot/widget.py,sha256=7IkjM13KWJ9rqTkhooSMHSE9LjR9PD4OPim4qbKvPcA,9648
|
|
56
|
-
qmlmathplot-0.4.
|
|
57
|
-
qmlmathplot-0.4.
|
|
58
|
-
qmlmathplot-0.4.
|
|
59
|
-
qmlmathplot-0.4.
|
|
56
|
+
qmlmathplot-0.4.4.dist-info/WHEEL,sha256=3NO1oYsF7mANFUWVdyEQLM-zmecczWWEmmF5rEbXrWk,80
|
|
57
|
+
qmlmathplot-0.4.4.dist-info/entry_points.txt,sha256=4z36D_RpPSYLiJDRM8iXnrSe1T4c2alfQJPcJTss3qY,54
|
|
58
|
+
qmlmathplot-0.4.4.dist-info/METADATA,sha256=3S69MPupAyqv4CRkCIDhcMY0T19VnW1sVKFUs9VfrAQ,53532
|
|
59
|
+
qmlmathplot-0.4.4.dist-info/RECORD,,
|
|
File without changes
|