Como funciona o Arctime no Metapost?

Como funciona o Arctime no Metapost?

Por favor, observe o seguinte código 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...

Por que s e t não são iguais? Quando adiciono um comprimento de arco, nada deve mudar, eu acho. Onde está o erro?

Editar: usei a versão 2.02 daqui: 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

Responder1

Não pretendo entender completamente o que arctimefaz e o algoritmo usado para calculá-lo. Verificando o código-fonte do MetaPost, no mp.warquivo (você pode tentar compilar este arquivo CWEB para PDF usando cweave, mas alguns _s não são prefixados com \_o que causa erro quando TeXed), seção 405, "As operações arclength e arctime são baseadas em um recurso recursivo função que encontra o comprimento do arco de uma spline cúbica dada dz0, dz1, dz2..." e a implementação real é a mp_get_arc_timefunção na seção 419.

Ao ler essas seções, o que entendi é que arctimeé implementado pela descoberta de zero, usando pesquisa binária em número flutuante (ou ponto fixo), para implementar a função inversa de mp_do_arc_test().

Se estiver usando MetaPost na linha de comando com ponto fixo padrão de 32 bits (também conhecido como escalonado), epsilon = 0.00002.

Ohttp://www.tlhiv.org/mppreview/usa double, que define epsilon = 1.52587890625e-05e outros sistemas numéricos usam valores semelhantes.

A seção 419 diz:

Se arc0 for maior que o comprimento do arco de um caminho cíclico h, o resultado será um valor de tempo maior que o comprimento do caminho.

onde arc0está o argumento numérico fornecido para arctime.

Usando um exemplo modificado da pergunta,

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;

Usando o sistema numérico em escala padrão:

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

usando-numbersystem=double

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

Parece-me que t=5.92é o valor correto que se enquadra nesta descrição, e o resultado pode ser interpretado usando t = s + l, onde lestá o comprimento do caminho cíclico p, que é comprimento 3. E além disso se enquadra na descrição do Manual MetaPost sobre o comportamento de arctimeo que dizarclength subpath (0,t) of p = a

Portanto, é muito provável que o t=2.67...resultado indique um bug devido aos diferentes sistemas numéricos adicionados.

Responder2

Atualização adicional: a equipe de desenvolvimento postou uma correção no repositório. Tirei-o de lá e construí-o localmente e parece bom. Usando o exemplo colado abaixo, agora entendo o seguinte:

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

e semelhante aos outros sistemas numéricos. Essa correção sem dúvida chegará às distribuições padrão no devido tempo.

Respondendo à pergunta original

O arctimeoperador em MP retorna o tempo tem um caminho quando arclengtho caminho atinge o comprimento desejado em pontos PostScript.

Então, se pé um caminho e atem o comprimento desejado, então arctime a of pdá o tempo ttal que arclength subpath(0, t) of p = a. Em todo o uso normal, você deve certificar-se de que o comprimento desejado aesteja entre 0 e arclength p.

Mas se o caminho pfor cíclico, você poderá fornecer um comprimento maior. Isso é semelhante ao modo como você pode consultar point 9 of fullcircleetc. Se você examinar o código-fonte, verá que o MP fornece especificamente que o comprimento desejado seja maior que o comprimento real de um caminho cíclico. O algoritmo trabalha ao longo do caminho ponto a ponto e se voltar ao início de um ciclo ele faz um cálculo para encurtar o resto do processo (se você realmente quiser os detalhes você pode examinar o código fonte).

A implementação deste cálculo causou um bug nos novos sistemas numéricos e que já foi corrigido. Parabéns à equipe de desenvolvimento pela solução rápida.


Atualizar: a equipe de desenvolvimentoconfirmeque isso parece um bug devido ao uso de matemática inteira implícita no código-fonte do MP.


Este é realmente um comentário, mas as seções do arquivo de log são muito longas, então estou respondendo.

Com a versão atual do MP, acho que seu exemplo fornece os resultados esperados com o antigo scaledsistema numérico. Mas resultados “inesperados” com qualquer um dos três novos sistemas. Isso parece algo para relatar à equipe de desenvolvimento.

Se eu adicionar algumas linhas ao exemplo do OP, assim:

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

Então eu recebo este arquivo de log se eu mpostusar o sistema numérico padrão:

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

Mas se eu usar qualquer um dos outros três sistemas numéricos, obtenho o valor "inesperado" do tprimeiro relatado. Então, aparentemente, algo dá errado no cálculo arclengthde um caminho cíclico usando os novos sistemas numéricos.

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

Na minha experiência com MP, o scaledsistema antigo é quase sempre melhor. O OP pode pedir ao proprietário do visualizador em thiv.org para usar o sistema numérico padrão, a menos que seja especificamente solicitado de outra forma.

informação relacionada