請看下面的 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 arctime
。arclength 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
時間。t
arclength
因此,如果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 預覽器的擁有者使用預設數位系統,除非另有明確要求。