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沒有前綴,\_這會導致TeXed時出錯),第405節,「arclength和arctime操作都基於遞歸函數,求給定dz0、dz1、dz2... 的三次樣條的弧長”,實際實現是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 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.

與其他數字系統類似。毫無疑問,這個修復將在適當的時候進入標準發行版。

回答原來的問題

當路徑達到所需長度(以 PostScript 點為單位)時,MP 中的運算子會傳迴路徑上的arctime時間。tarclength

因此,如果p是一條路徑,並且a是所需的長度,則arctime a of p給予的時間t使得arclength subpath(0, t) of p = a。在所有正常使用中,您應該確保所需的長度a在 0 和 之間arclength p

但如果路徑p恰好是循環的,那麼你可以給出更長的長度。這與你可以參考etc的方式類似point 9 of fullcircle。該演算法沿著路徑逐點工作,如果它回到循環的開始,它會進行計算以縮短過程的其餘部分(如果您確實想要詳細信息,您可以檢查源代碼)。

此計算的實施導致了新數字系統的錯誤,現已修正。感謝開發團隊的快速修復。


更新: 開發團隊確認由於在 MP 原始程式碼中使用了隱式整數數學,這看起來像是一個錯誤。


這確實是一條評論,但日誌檔案部分太長,所以我回答這個。

在目前版本的 MP 中,我發現您的範例使用舊scaled數字系統給出了預期結果。但這三個新系統中的任何一個都會產生「意想不到的」結果。這看起來像是要向開發團隊報告的事情。

如果我在 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

但如果我使用其他三個數字系統中的任何一個,我會得到第一個報告的「意外」值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 預覽器的擁有者使用預設數位系統,除非另有明確要求。

相關內容