Bitte schauen Sie sich den folgenden Metapost-Code an:
path p;
p = (0,0){up}..{right}(200,100)..{up}(300,400)..cycle;
len := arclength p;
s := arctime (2500) of p;
t := arctime (len+2500) of p;
draw p;
show len;% 2799
show s;% 2.92...
show t;% 2.67...
Warum sind s und t nicht gleich? Wenn ich eine Bogenlänge addiere, sollte sich doch nichts ändern, denke ich. Wo ist der Fehler?
Bearbeiten: Ich habe Version 2.02 von hier verwendet: http://www.tlhiv.org/mppreview/
This is MetaPost, version 2.02 (TeX Live 2023) (kpathsea version 6.3.5) 28 APR 2024 02:47
**preview.mp
(/usr/share/texlive/texmf-dist/metapost/base/mpost.mp
(/usr/share/texlive/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./preview.mp
>> 2799.0210591829564
>> 2.9211035593209118
>> 2.6795082428530486 [0] )
1 output file written: preview.mps
Antwort1
Ich behaupte nicht, dass ich vollständig verstehe, was es arctime
bedeutet und welcher Algorithmus zur Berechnung verwendet wird. Überprüfen Sie den MetaPost-Quellcode in der mp.w
Datei (Sie können versuchen, diese CWEB-Datei mit cweave in PDF zu kompilieren, aber einige _
s sind nicht mit einem Präfix versehen \_
, was beim TeXen zu Fehlern führt), Abschnitt 405, „Die Operationen arclength und arctime basieren beide auf einer rekursiven Funktion, die die Bogenlänge eines kubischen Splines bei dz0, dz1, dz2 ... berechnet“, und die tatsächliche Implementierung ist die mp_get_arc_time
Funktion in Abschnitt 419.
Durch das Lesen dieser Abschnitte habe ich verstanden, dass arctime
die Implementierung durch Nullsuche mithilfe einer binären Suche nach Gleitkommazahlen (oder Festkommazahlen) erfolgt, um die Umkehrfunktion von zu implementieren mp_do_arc_test()
.
Bei Verwendung von MetaPost in der Befehlszeile mit standardmäßigem 32-Bit-Festkomma (auch skaliert genannt), epsilon = 0.00002
.
Derhttp://www.tlhiv.org/mppreview/verwendet das Doppelte, das festlegt epsilon = 1.52587890625e-05
, und andere Zahlensysteme verwenden alle ähnliche Werte.
Der Abschnitt 419 besagt:
Wenn arc0 größer als die Bogenlänge eines zyklischen Pfades h ist, ist das Ergebnis ein Zeitwert, der größer als die Länge des Pfades ist.
wobei arc0
das für bereitgestellte numerische Argument ist arctime
.
Anhand eines abgewandelten Beispiels aus der Frage:
path p;
p = (0,0){up}..{right}(200,100)..{up}(300,400)..cycle;
len := arclength p;
s := arctime (2500) of p;
t := arctime (len+2500) of p;
show len;
show s;
show t;
show epsilon;
show arclength subpath (0,t) of p;
show len+2500;
end;
Verwenden des standardmäßigen skalierten Zahlensystems:
>> 2799.02077
>> 2.92111
>> 5.92111
>> 0.00002
>> 5299.043
>> 5299.02077
mit-numbersystem=double
>> 2799.0210591829564
>> 2.9211035593209118
>> 2.6795082428530486
>> 1.52587890625e-05
>> 2200.7155501530865
>> 5299.0210591829564
Mir scheint, dass dies t=5.92
der richtige Wert ist, der zu dieser Beschreibung passt, und das Ergebnis kann mit interpretiert werden t = s + l
, wobei l
die Länge des zyklischen Pfads ist p
, also die Länge 3. Außerdem passt es zur Beschreibung des Verhaltens im MetaPost-Handbuch, in arctime
der es heißt:arclength subpath (0,t) of p = a
Daher ist es sehr wahrscheinlich, dass das t=2.67...
Ergebnis auf einen Fehler aufgrund der hinzugefügten unterschiedlichen Zahlensysteme hinweist.
Antwort2
Weiteres Update: Das Entwicklerteam hat einen Fix im Repository veröffentlicht. Ich habe ihn von dort heruntergeladen und lokal erstellt und er sieht gut aus. Mit dem unten eingefügten Beispiel erhalte ich jetzt Folgendes:
> mpost b.mp
This is MetaPost, version 2.11 (TeX Live 2025/dev) (kpathsea version 6.4.0/dev)
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.02077
>> 2.92111
>> 5.92111
>> 3
>> "scaled" [1] )
1 output file written: b.1
Transcript written on b.log.
> mpost -numbersystem=double b.mp
This is MetaPost, version 2.11 (TeX Live 2025/dev) (kpathsea version 6.4.0/dev)
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.0210591829564
>> 2.9211035593209118
>> 5.9211035593209118
>> 3
>> "double" [1] )
1 output file written: b.1
Transcript written on b.log.
und ähnliches von den anderen Zahlensystemen. Dieser Fix wird zweifellos zu gegebener Zeit in die Standardverteilungen aufgenommen.
Beantwortung der ursprünglichen Frage
Der arctime
Operator in MP gibt die Zeit t
auf einem Pfad zurück, bis arclength
dieser die gewünschte Länge in PostScript-Punkten erreicht.
Wenn also p
ein Pfad ist und a
die gewünschte Länge ist, dann arctime a of p
ergibt die Zeit t
so, dass arclength subpath(0, t) of p = a
. Bei der normalen Verwendung sollten Sie sicherstellen, dass die gewünschte Länge a
zwischen 0 und liegt arclength p
.
Wenn der Pfad jedoch p
zyklisch ist, können Sie eine längere Länge angeben. Dies ähnelt der Art und Weise, wie Sie auf point 9 of fullcircle
usw. verweisen können. Wenn Sie den Quellcode untersuchen, werden Sie feststellen, dass MP ausdrücklich vorsieht, dass die gewünschte Länge länger sein kann als die tatsächliche Länge eines zyklischen Pfads. Der Algorithmus arbeitet den Pfad Punkt für Punkt ab und führt, wenn er zum Anfang eines Zyklus zurückkehrt, eine Berechnung durch, um den Rest des Prozesses abzukürzen (wenn Sie die Details wirklich wissen möchten, können Sie den Quellcode untersuchen).
Die Implementierung dieser Berechnung verursachte einen Fehler mit den neuen Zahlensystemen, der nun behoben wurde. Ein großes Lob an das Entwicklungsteam für die schnelle Lösung.
Aktualisieren: das Entwicklungsteambestätigendass dies aufgrund der Verwendung impliziter Ganzzahlmathematik im MP-Quellcode wie ein Fehler aussieht.
Dies ist eigentlich ein Kommentar, aber die Abschnitte der Protokolldatei sind zu lang, deshalb antworte ich darauf.
Mit der aktuellen Version von MP stelle ich fest, dass Ihr Beispiel mit dem alten scaled
Zahlensystem die erwarteten Ergebnisse liefert. Aber mit jedem der drei neuen Systeme „unerwartete“ Ergebnisse. Das sieht nach etwas aus, das dem Entwicklungsteam gemeldet werden sollte.
Wenn ich dem OP-Beispiel ein paar Zeilen hinzufüge, etwa so:
beginfig(1);
path p;
p = (0,0){up}..{right}(200,100)..{up}(300,400)..cycle;
len := arclength p;
s := arctime (2500) of p;
t := arctime (len+2500) of p;
draw p;
show len;% 2799
show s;% 2.92...
show t;% 2.67...
show arctime arclength p of p;
show numbersystem;
endfig;
end
mpost
Wenn ich das Standardnummernsystem verwende, erhalte ich diese Protokolldatei :
This is MetaPost, version 2.10 (TeX Live 2024) (kpathsea version 6.4.0) 28 APR 2024 15:56
**b.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.02077
>> 2.92111
>> 5.92111
>> 3
>> "scaled" [1] )
1 output file written: b.1
Wenn ich jedoch eines der anderen drei Zahlensysteme verwende, erhalte ich den „unerwarteten“ Wert von t
zuerst gemeldet. Bei der Berechnung arclength
eines zyklischen Pfads mit den neuen Zahlensystemen läuft also anscheinend etwas schief.
:!mpost -numbersystem=double b.mp
This is MetaPost, version 2.10 (TeX Live 2024) (kpathsea version 6.4.0)
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.0210591829564
>> 2.9211035593209118
>> 2.6795082428530486
>> 3
>> "double" [1] )
1 output file written: b.1
Transcript written on b.log.
"b.log" 12L, 389B
:!mpost -numbersystem=decimal b.mp
This is MetaPost, version 2.10 (TeX Live 2024) (kpathsea version 6.4.0) 28 APR 2024 15:58
**b.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.021059182955437254465959453077
>> 2.921103559320912153438877894997069
>> 2.67950824285304864431956913069307
>> 3
>> "decimal" [1] )
1 output file written: b.1
:!mpost -numbersystem=binary b.mp
This is MetaPost, version 2.10 (TeX Live 2024) (kpathsea version 6.4.0) 28 APR 2024 15:58
**b.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/mpost.mp
(/usr/local/texlive/2024/texmf-dist/metapost/base/plain.mp
Preloading the plain mem file, version 1.005) ) (./b.mp
>> 2799.0210591829554372544659594531163
>> 2.9211035593209121534388778949970568
>> 2.6795082428530486443195691306930351
>> 3
>> "binary" [1] )
1 output file written: b.1
Meiner Erfahrung mit MP zufolge scaled
ist das alte System fast immer besser. Der OP sollte den Besitzer des Previewers bei thiv.org bitten, das Standardnummernsystem zu verwenden, sofern nicht ausdrücklich etwas anderes verlangt wird.