Timeline: safely calculate the fraction of a very large timespan
...using a requantisation trick to cancel out some factors in the product of two rational numbers, allowing to calculate the product without actual multiplication of (dangerously large) numbers. with these additional safeguards, the anchorWindowAtPosition() succeeds without Integer-wrap, but the result is not fully correct (some further calculation error hidden somewhere??)
This commit is contained in:
parent
b898f1514b
commit
7007101357
6 changed files with 215 additions and 16 deletions
|
|
@ -139,6 +139,13 @@ namespace util {
|
|||
< 63;
|
||||
}
|
||||
|
||||
inline bool
|
||||
can_represent_Product (Rat a, Rat b)
|
||||
{
|
||||
return can_represent_Product(a.numerator(), b.numerator())
|
||||
and can_represent_Product(a.denominator(), b.denominator());
|
||||
}
|
||||
|
||||
inline bool
|
||||
can_represent_Sum (Rat a, Rat b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -283,8 +283,11 @@ namespace time {
|
|||
|
||||
|
||||
/** constant to indicate "no duration" */
|
||||
const Duration Duration::NIL (Time::ZERO);
|
||||
const Duration Duration::NIL {Time::ZERO};
|
||||
|
||||
/** maximum possible temporal extension */
|
||||
const Duration Duration::MAX {Offset{Time::MIN, Time::MAX}};
|
||||
|
||||
|
||||
}} // namespace lib::Time
|
||||
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ namespace time {
|
|||
{ }
|
||||
|
||||
static const Duration NIL;
|
||||
static const Duration MAX ;
|
||||
|
||||
void accept (Mutation const&);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ namespace model {
|
|||
|
||||
using util::Rat;
|
||||
using util::rational_cast;
|
||||
using util::can_represent_Product;
|
||||
using util::reQuant;
|
||||
|
||||
using util::min;
|
||||
using util::max;
|
||||
|
|
@ -166,7 +168,7 @@ namespace model {
|
|||
const FSecs DEFAULT_CANVAS{23};
|
||||
const Rat DEFAULT_METRIC{25};
|
||||
const uint MAX_PX_WIDTH{1000000};
|
||||
const FSecs MAX_TIMESPAN{_FSecs(Time::MAX-Time::MIN)};
|
||||
const FSecs MAX_TIMESPAN{_FSecs(Duration::MAX)};
|
||||
const FSecs MICRO_TICK{1_r/Time::SCALE};
|
||||
|
||||
/** Maximum quantiser to be handled in fractional arithmetics without hazard.
|
||||
|
|
@ -174,15 +176,15 @@ namespace model {
|
|||
* DENOMINATOR * Time::Scale has to stay below INT_MAX, with some safety margin
|
||||
*/
|
||||
const int64_t LIM_HAZARD{int64_t{1} << 40 };
|
||||
const int64_t HAZARD_DEGREE{util::ilog2(LIM_HAZARD)};
|
||||
|
||||
inline int
|
||||
toxicDegree (Rat poison)
|
||||
toxicDegree (Rat poison, const int64_t THRESHOLD =HAZARD_DEGREE)
|
||||
{
|
||||
const int64_t HAZARD_DEGREE{util::ilog2(LIM_HAZARD)};
|
||||
int64_t magNum = util::ilog2(abs(poison.numerator()));
|
||||
int64_t magDen = util::ilog2(abs(poison.denominator()));
|
||||
int64_t degree = max (magNum, magDen);
|
||||
return max (0, degree - HAZARD_DEGREE);
|
||||
return max (0, degree - THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +428,7 @@ namespace model {
|
|||
setVisiblePos (Rat percentage)
|
||||
{
|
||||
FSecs canvasDuration{afterAll_-startAll_};
|
||||
anchorWindowAtPosition (canvasDuration*percentage);
|
||||
anchorWindowAtPosition (scaleSafe (canvasDuration, percentage));
|
||||
fireChangeNotification();
|
||||
}
|
||||
|
||||
|
|
@ -495,18 +497,48 @@ namespace model {
|
|||
* is thus specific to the ZoomWindow implementation. To sanitise, the denominator
|
||||
* is reduced logarithmically (bit-shift) sufficiently and then used as new quantiser,
|
||||
* thus ensuring that both denominator (=quantiser) and numerator are below limit.
|
||||
* @warning the rational number must not be to large overall; this heuristic will fail
|
||||
* on fractions with very large numerator and small denominator — however, for
|
||||
* the ZoomWindow, this case is not relevant, since the zoom factor is limited,
|
||||
* and other usages of rational numbers can be range checked explicitly.
|
||||
* @note the check is based on the 2-logarithm of numerator and denominator, which is
|
||||
* pretty much the fastest possibility (even a simple comparison would have
|
||||
* to do the same). Values below threshold are simply passed-through.
|
||||
* to do the same). Values below threshold are simply passed-through.
|
||||
*/
|
||||
static Rat
|
||||
detox (Rat poison)
|
||||
{
|
||||
int toxicity = toxicDegree (poison);
|
||||
return toxicity ? util::reQuant(poison, poison.denominator() >> toxicity)
|
||||
return toxicity ? reQuant (poison, max (poison.denominator() >> toxicity, 64))
|
||||
: poison;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale a possibly large time duration by a rational factor, while attempting to avoid
|
||||
* integer wrap-around. Obviously this is only a heuristic, yet adequate within the
|
||||
* framework of ZoomWindow, where the end result is pixel aligned anyway.
|
||||
*/
|
||||
static FSecs
|
||||
scaleSafe (FSecs duration, Rat factor)
|
||||
{
|
||||
auto approx = [](Rat r){ return rational_cast<double> (r); };
|
||||
|
||||
if (not util::can_represent_Product(duration, factor))
|
||||
{
|
||||
if (approx(MAX_TIMESPAN) < approx(duration) * approx (factor))
|
||||
return MAX_TIMESPAN; // exceeds limits of time representation => cap the result
|
||||
|
||||
// slightly adjust the factor so that the time-base denominator cancels out,
|
||||
// allowing to calculate the product without dangerous multiplication of large numbers
|
||||
factor = 1_r / reQuant (1_r/factor, duration.denominator());
|
||||
return detox (duration * factor);
|
||||
}
|
||||
else
|
||||
// just calculate ordinary numbers...
|
||||
return duration * factor;
|
||||
}
|
||||
|
||||
|
||||
static Rat
|
||||
establishMetric (uint pxWidth, Time startWin, Time afterWin)
|
||||
{
|
||||
|
|
@ -732,7 +764,7 @@ namespace model {
|
|||
FSecs duration{afterWin_-startWin_};
|
||||
Rat posFactor = canvasOffset / FSecs{afterAll_-startAll_};
|
||||
posFactor = parabolicAnchorRule (posFactor); // also limited 0...1
|
||||
FSecs partBeforeAnchor = posFactor * duration;
|
||||
FSecs partBeforeAnchor = scaleSafe (duration, posFactor);
|
||||
startWin_ = startAll_ + (canvasOffset - partBeforeAnchor);
|
||||
establishWindowDuration (duration);
|
||||
startAll_ = min (startAll_, startWin_);
|
||||
|
|
@ -815,6 +847,8 @@ namespace model {
|
|||
parabolicAnchorRule (Rat posFactor)
|
||||
{
|
||||
posFactor = util::limited (0, posFactor, 1);
|
||||
if (toxicDegree(posFactor, 20)) // prevent integer wrap
|
||||
posFactor = util::reQuant(posFactor, 1 << 20);
|
||||
posFactor = (2*posFactor - 1); // -1 ... +1
|
||||
posFactor = posFactor*posFactor*posFactor; // -1 ... +1 but accelerating towards boundaries
|
||||
posFactor = (posFactor + 1) / 2; // 0 ... 1
|
||||
|
|
|
|||
|
|
@ -399,9 +399,11 @@ namespace test {
|
|||
|
||||
win.setVisiblePos(0.50);
|
||||
CHECK (win.visible() == TimeSpan(_t((40/2-16) -8), FSecs(16))); // window positioned to centre of canvas
|
||||
CHECK (win.visible().start() == _t(-4)); // (canvas was already positioned asymmetrically)
|
||||
|
||||
win.setVisiblePos(-0.50);
|
||||
CHECK (win.visible() == TimeSpan(_t(-16-40/2), FSecs(16))); // relative positioning not limited at lower bound
|
||||
CHECK (win.visible().start() == _t(-36)); // (causing also further expansion of canvas)
|
||||
win.setVisiblePos(_t(200)); // absolute positioning likewise not limited
|
||||
CHECK (win.visible() == TimeSpan(_t(200-16), FSecs(16))); // but anchored according to relative anchor pos
|
||||
CHECK (win.px_per_sec() == 80); // metric retained
|
||||
|
|
@ -580,13 +582,16 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/** @test verify ZoomWindow code can handle "poisonous" Zoom-Factor parameters
|
||||
/** @test verify ZoomWindow code can handle "poisonous" fractional number parameters
|
||||
* - toxic zoom factor passed through ZoomWindow::setMetric(Rat)
|
||||
* - toxic proportion factor passed to ZoomWindow::setVisiblePos(Rat)
|
||||
* - indirectly cause toxic posFactor in ZoomWindow::anchorWindowAtPosition(FSecs)
|
||||
* by providing a target position very far off current window location
|
||||
*/
|
||||
void
|
||||
safeguard_poisonousMetric()
|
||||
{
|
||||
|
||||
ZoomWindow win{};
|
||||
ZoomWindow win{};
|
||||
CHECK (win.visible() == win.overallSpan()); // by default window spans complete canvas
|
||||
CHECK (win.visible().duration() == _t(23)); // ...and has just some handsome extension
|
||||
CHECK (win.px_per_sec() == 25);
|
||||
|
|
@ -624,6 +629,26 @@ namespace test {
|
|||
CHECK(856.350708f == rational_cast<float> (_FSecs(win.visible().duration())));
|
||||
CHECK (win.px_per_sec() == 575000000_r/856350691); // the new metric however is comprised of sanitised fractional numbers
|
||||
CHECK (win.pxWidth() == 575); // and the existing pixel width was not changed
|
||||
|
||||
SHOW_EXPR(win.overallSpan());
|
||||
SHOW_EXPR(_raw(win.visible().duration()));
|
||||
SHOW_EXPR(win.px_per_sec());
|
||||
SHOW_EXPR(win.pxWidth());
|
||||
win.setVisiblePos (poison); // Yet another way to sneak in our toxic value...
|
||||
SHOW_EXPR(win.overallSpan());
|
||||
SHOW_EXPR(_raw(win.overallSpan()));
|
||||
SHOW_EXPR(_raw(win.overallSpan().duration()));
|
||||
SHOW_EXPR(_raw(win.visible().duration()));
|
||||
SHOW_EXPR(win.px_per_sec());
|
||||
SHOW_EXPR(win.pxWidth());
|
||||
SHOW_EXPR(_raw(win.overallSpan().duration()) * rational_cast<double> (poison))
|
||||
Time targetPos{TimeValue{gavl_time_t(_raw(win.overallSpan().duration()) * rational_cast<double> (poison))}};
|
||||
SHOW_EXPR(targetPos);
|
||||
SHOW_EXPR(_raw(targetPos));
|
||||
SHOW_EXPR(_raw(win.visible().start()))
|
||||
SHOW_EXPR(_raw(win.visible().end()))
|
||||
SHOW_EXPR(bool(win.visible().start() < targetPos))
|
||||
SHOW_EXPR(bool(win.visible().end() > targetPos))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39764,9 +39764,48 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668267251650" ID="ID_1280626173" MODIFIED="1668267290312" TEXT="potentieller TimeValue-wrap">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1669507976363" ID="ID_1360914257" MODIFIED="1669508005798" TEXT="Duration und Canvas-size können groß sein">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1669507940458" ID="ID_355998747" MODIFIED="1669507940458" TEXT="Rat posFactor = canvasOffset / FSecs{afterAll_-startAll_};"/>
|
||||
<node CREATED="1669507965470" ID="ID_1858701509" MODIFIED="1669507965470" TEXT="FSecs partBeforeAnchor = posFactor * duration;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1668267393360" ID="ID_1700728412" MODIFIED="1668267398176" TEXT="giftige Brüche">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669508070174" ID="ID_171647736" MODIFIED="1669508178509" TEXT="Aua: so ziemlich alles kann hier giftig sein">
|
||||
<linktarget COLOR="#e32c65" DESTINATION="ID_171647736" ENDARROW="Default" ENDINCLINATION="8;76;" ID="Arrow_ID_1341085031" SOURCE="ID_196873456" STARTARROW="None" STARTINCLINATION="577;-36;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1669508081900" ID="ID_1740115162" MODIFIED="1669508382889" TEXT="zwar kann das Ergebnis nicht grob entgleisen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1669508094694" ID="ID_1971396713" MODIFIED="1669508365178" TEXT="konsistentes Verhalten ist aber schwer aufrecht zu erhalten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und zwar dann, wenn auch noch die Window-Parameter extrem sind — dann sieht die Lage ziemlich hoffnungslos aus
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1669508366255" ID="ID_1644190283" MODIFIED="1669682752758" TEXT="Idee: auf gleichen Nenner normalisieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn dadurch würde man die kreuzweise Multiplikation verhindern
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#fbf8c7" DESTINATION="ID_267834802" ENDARROW="Default" ENDINCLINATION="538;-591;" ID="Arrow_ID_1957682133" STARTARROW="None" STARTINCLINATION="668;44;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1668267422500" ID="ID_17566048" MODIFIED="1668267468507" TEXT="parabolicAnchorRule">
|
||||
<arrowlink COLOR="#e92c3f" DESTINATION="ID_1689286236" ENDARROW="Default" ENDINCLINATION="82;-4;" ID="Arrow_ID_176217068" STARTARROW="None" STARTINCLINATION="-158;21;"/>
|
||||
</node>
|
||||
|
|
@ -39883,8 +39922,12 @@
|
|||
<node COLOR="#338800" CREATED="1669478154709" ID="ID_499422673" MODIFIED="1669488173372" TEXT="Fall-2 : hinreichend großer Canvas">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669479930775" ID="ID_196873456" MODIFIED="1669480034941" TEXT="Fall-3 : setVisiblePos mit giftigem faktor">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669479930775" ID="ID_196873456" MODIFIED="1669508183093" TEXT="Fall-3 : setVisiblePos mit giftigem faktor">
|
||||
<arrowlink COLOR="#e32c65" DESTINATION="ID_171647736" ENDARROW="Default" ENDINCLINATION="8;76;" ID="Arrow_ID_1341085031" STARTARROW="None" STARTINCLINATION="577;-36;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1669682888293" HGAP="67" ID="ID_1431682003" MODIFIED="1669682917272" TEXT="erweist sich als ziemlich schwer unter Kontrolle zu bekommen" VSHIFT="-1">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669480019215" ID="ID_930072077" MODIFIED="1669480034942" TEXT="Fall-4 : setVisiblePos mit extrem entfernter Position">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -39904,7 +39947,7 @@
|
|||
<linktarget COLOR="#e62f5c" DESTINATION="ID_651838862" ENDARROW="Default" ENDINCLINATION="115;-4;" ID="Arrow_ID_1930230162" SOURCE="ID_1257614207" STARTARROW="None" STARTINCLINATION="-189;14;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1668270062492" ID="ID_1671513743" MODIFIED="1668736241536" TEXT="entgiftungs-Methode schaffen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1668270062492" ID="ID_1671513743" MODIFIED="1669680251895" TEXT="entgiftungs-Methoden schaffen">
|
||||
<linktarget COLOR="#bf0f5b" DESTINATION="ID_1671513743" ENDARROW="Default" ENDINCLINATION="297;-23;" ID="Arrow_ID_389982782" SOURCE="ID_1175951405" STARTARROW="None" STARTINCLINATION="-323;20;"/>
|
||||
<linktarget COLOR="#9a858e" DESTINATION="ID_1671513743" ENDARROW="Default" ENDINCLINATION="297;-23;" ID="Arrow_ID_1815772846" SOURCE="ID_148236436" STARTARROW="None" STARTINCLINATION="-292;20;"/>
|
||||
<linktarget COLOR="#b18586" DESTINATION="ID_1671513743" ENDARROW="Default" ENDINCLINATION="256;-19;" ID="Arrow_ID_882084800" SOURCE="ID_773636992" STARTARROW="None" STARTINCLINATION="-201;12;"/>
|
||||
|
|
@ -40275,12 +40318,37 @@
|
|||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1668705828544" ID="ID_27322947" MODIFIED="1668705883187" TEXT="lb(zähler) - lb(nenner) ⟼ zusatz-Faktor"/>
|
||||
<node CREATED="1668705906923" ID="ID_21115436" MODIFIED="1668705925067" TEXT="bei Überschuß den Quantiser entsprechend reduzieren"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669508782375" ID="ID_1328009916" MODIFIED="1669673876153" TEXT="Vorsicht: Quantiser kann Null werden">
|
||||
<arrowlink COLOR="#dd2238" DESTINATION="ID_507738124" ENDARROW="Default" ENDINCLINATION="93;-57;" ID="Arrow_ID_377645167" STARTARROW="None" STARTINCLINATION="-217;15;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1669673789135" ID="ID_846083949" MODIFIED="1669673797869" TEXT="dieser Ansatz hat seine Grenzen">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1669673800862" ID="ID_507738124" MODIFIED="1669673869569" TEXT="absolut sehr große Brüche können wir nicht handhaben">
|
||||
<linktarget COLOR="#dd2238" DESTINATION="ID_507738124" ENDARROW="Default" ENDINCLINATION="93;-57;" ID="Arrow_ID_377645167" SOURCE="ID_1328009916" STARTARROW="None" STARTINCLINATION="-217;15;"/>
|
||||
</node>
|
||||
<node CREATED="1669673828418" ID="ID_1875664128" MODIFIED="1669673980107" TEXT="für solche Fälle würde sogar die "Bereinigung" selber entgleisen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Und zwar, wenn der Nenner viel kleiner ist als der Zähler, und der Zähler extrem groß. Dann würde nämlich die Ganzzahl-Division keine signifikante Verringerung der Dimension bewirken, und die anschließende re-Quantisierung das Ergebnis (bedingt durch die Normierung auf einen gemeinsamen Nenner) sogar noch vergrößern
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1669673981445" ID="ID_1599443715" MODIFIED="1669673998427" TEXT="allerdings für Zoom-Faktoren können wir das ausschließen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1668705939639" ID="ID_393310295" MODIFIED="1668736180984" TEXT="Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1668705939639" ID="ID_393310295" MODIFIED="1669680301519" TEXT="allgemeiner Entgiftungs-Filter">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1668705949188" ID="ID_510681740" MODIFIED="1668707393273" TEXT="2-er-Logarithmen berechnen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1668705960324" ID="ID_1999378206" MODIFIED="1668705972646" TEXT="ist die effizientest mögliche Lösung">
|
||||
|
|
@ -40300,6 +40368,26 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1669680303553" ID="ID_943604336" MODIFIED="1669680329806" TEXT="Handhabung extremer Zeitspannen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1669680334284" ID="ID_1144877898" MODIFIED="1669680352726" TEXT="Probleme">
|
||||
<node CREATED="1669680353674" ID="ID_380004829" MODIFIED="1669680374859" TEXT="Summen mit Brüchen"/>
|
||||
<node CREATED="1669680375968" ID="ID_861847594" MODIFIED="1669680389409" TEXT="Verhältnis-Berechnung"/>
|
||||
<node CREATED="1669680390181" ID="ID_136457686" MODIFIED="1669680403199" TEXT="Anteil-Berechnung"/>
|
||||
</node>
|
||||
<node CREATED="1669680416417" ID="ID_264195573" MODIFIED="1669680423082" TEXT="Lösungs-Techniken">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1669680424602" ID="ID_267834802" MODIFIED="1669682824592" TEXT="Kürzungs-Trick">
|
||||
<linktarget COLOR="#fbf8c7" DESTINATION="ID_267834802" ENDARROW="Default" ENDINCLINATION="538;-591;" ID="Arrow_ID_1957682133" SOURCE="ID_1644190283" STARTARROW="None" STARTINCLINATION="668;44;"/>
|
||||
<node CREATED="1669680431912" ID="ID_180315930" MODIFIED="1669680447650" TEXT="einen Partner re-Quantisieren"/>
|
||||
<node CREATED="1669680448333" ID="ID_969768863" MODIFIED="1669680473406" TEXT="so daß sich dann kreuzweise ein Zähler/Nenner wegkürzen"/>
|
||||
<node CREATED="1669680479307" ID="ID_503307048" MODIFIED="1669680497907" TEXT="⟹ danach können wir Produkt oder Quotient ohne Multipliaktion berechnen"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1669682825470" ID="ID_906501375" MODIFIED="1669682838860" TEXT="verallgemeinert: scaleSafe()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668707398858" ID="ID_1529383789" MODIFIED="1668707464339" TEXT="Test">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1668707465449" ID="ID_1678870601" MODIFIED="1668736173820" TEXT="toxicDegree mit einigen Beispielen demonstrieren">
|
||||
|
|
@ -40307,6 +40395,47 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668707479892" ID="ID_1964644327" MODIFIED="1668707490200" TEXT="ansonsten durch Ausreizen der Extremwerte testen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1669682928809" ID="ID_499417740" MODIFIED="1669682938471" TEXT="setVisiblePos(gift)">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1669682950712" ID="ID_1730356591" MODIFIED="1669682974366" TEXT="macht was Anderes als nur die Zoom-Metrik anpassen"/>
|
||||
<node CREATED="1669682975415" ID="ID_1386857509" MODIFIED="1669682993901" TEXT="die Verbindung mit Längen/Positions-Kalkulationen ist gefährlich">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1669683004871" ID="ID_1503834170" MODIFIED="1669683025116" TEXT="wrap-around bekomme ich mit detox() und scaleSafe() in den Griff">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1669683026004" ID="ID_1867241917" MODIFIED="1669683139814" TEXT="Ergebnis ist aber noch nicht plausibel">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# _raw(win.overallSpan().duration()) ? = 307445734561825860 </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# _raw(targetPos) ?                    = 206435633551724864 </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# _raw(win.visible().start()) ?        =   2248731193323487 </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# _raw(win.visible().end()) ?          =   2248732049674178 </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# bool(win.visible().start() < targetPos) ? = 1 </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced">#--◆--# bool(win.visible().end() > targetPos) ? = 0 </font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669683157298" ID="ID_710000990" MODIFIED="1669683199793" TEXT="Fenster liegt verdächtig weit daneben">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue