Metapost の arctime はどのように機能しますか?

Metapost の arctime はどのように機能しますか?

次の Metapost コードをご覧ください。

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...

なぜ s と t は同じではないのですか? 弧長を追加しても何も変わらないと思います。どこに間違いがあるのでしょうか?

編集: ここからバージョン 2.02 を使用しました: 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

答え1

arctime私は、それが何をするのか、またそれを計算するために使用されたアルゴリズムを完全に理解していると主張しません。MetaPost ソース コードを確認すると、mp.wファイル (cweave を使用してこの CWEB ファイルを PDF にコンパイルできますが、一部の_s に接頭辞が付いていないため、\_TeX で変換するとエラーが発生します) のセクション 405、「arclength および arctime 操作はどちらも、dz0、dz1、dz2... が与えられた 3 次スプラインの弧の長さを求める再帰関数に基づいています」とあり、実際の実装はmp_get_arc_timeセクション 419 の関数です。

これらのセクションを読んで、私が理解したのは、 はarctime、浮動小数点数 (または固定小数点数) のバイナリ検索を使用してゼロ検索によって実装され、 の逆関数を実装するということですmp_do_arc_test()

デフォルトの 32 ビット固定小数点 (スケーリングとも呼ばれます) を使用してコマンド ラインで MetaPost を使用する場合、epsilon = 0.00002.

http://www.tlhiv.org/mppreview/は double を使用し、 を設定しますepsilon = 1.52587890625e-05。他の数値システムではすべて同様の値が使用されます。

第419条にはこう記されている。

arc0 が循環パス h の円弧の長さより大きい場合、結果はパスの長さより大きい時間値になります。

ここで、arc0は に提供される数値引数ですarctime

質問の修正例を使用すると、

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;

デフォルトのスケール数値システムを使用する:

>> 2799.02077
>> 2.92111
>> 5.92111
>> 0.00002
>> 5299.043
>> 5299.02077

使用して-numbersystem=double

>> 2799.0210591829564
>> 2.9211035593209118
>> 2.6795082428530486
>> 1.52587890625e-05
>> 2200.7155501530865
>> 5299.0210591829564

は、この説明に合う正しい値であるように思われt=5.92、結果は を使って解釈できますt = s + l。ここで、 はl巡回パス の長さでp、長さは3です。さらに、これは の挙動に関するMetaPostマニュアルの説明に適合しますarctimearclength subpath (0,t) of p = a

t=2.67...したがって、異なる数値システムが追加されたために、結果にバグが発生した可能性が非常に高くなります。

答え2

さらなるアップデート: 開発チームがリポジトリに修正を投稿しました。そこからプルしてローカルでビルドしたところ、うまくいきました。以下に貼り付けた例を使用すると、次のようになります。

> 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.

他の数値システムでも同様です。この修正は、やがて標準ディストリビューションに間違いなく組み込まれるでしょう。

元の質問に答える

MP の演算子は、パスが PostScript ポイントで目的の長さに達したときのパス上のarctime時間を返します。tarclength

したがって、pがパスで がa目的の長さである場合、 は となるarctime a of p時間を与えます。通常の使用では、目的の長さが 0 から の間であることを確認する必要があります。tarclength subpath(0, t) of p = aaarclength p

しかし、パスがp循環的である場合は、より長い長さを指定できます。これは、point 9 of fullcircleなどを参照する方法に似ています。ソース コードを調べると、MP では、希望する長さが循環パスの実際の長さよりも長くなるように明示的に指定されていることがわかります。アルゴリズムはパスに沿ってポイントごとに動作し、サイクルの先頭に戻ると、残りのプロセスをショートカットする計算を行います (詳細が必要な場合は、ソース コードを調べることができます)。

この計算の実装により、新しい数値システムでバグが発生しましたが、現在は修正されています。迅速な修正を行った開発チームに感謝します。


アップデート: 開発チーム確認するこれは、MP ソース コードで暗黙的な整数演算を使用しているために発生するバグのようです。


これは実際にはコメントですが、ログ ファイルのセクションが長すぎるため、これに回答します。

現在のバージョンの MP では、古い数値システムでは例によって期待どおりの結果が出ていることがわかりましたscaled。しかし、3 つの新しいシステムでは「予期しない」結果が出ています。これは開発チームに報告すべきことのようです。

OP の例に数行追加すると、次のようになります。

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デフォルトの数値システムを使用して実行すると、次のログ ファイルが生成されます。

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

しかし、他の 3 つの数値システムのいずれかを使用すると、t最初に報告された の「予期しない」値が得られます。したがって、新しい数値システムを使用して循環パスの を計算するときに、何か問題が発生しているようですarclength

:!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

私の MP の経験では、古いscaledシステムの方がほとんどの場合優れています。OP は、特に要求がない限り、デフォルトの番号システムを使用するように thiv.org のプレビューアーの所有者に依頼するとよいかもしれません。

関連情報