¿Cómo funciona arctime en Metapost?

¿Cómo funciona arctime en Metapost?

Mire el siguiente 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 qué s y t no son lo mismo? Creo que cuando agrego una longitud de arco, nada debería cambiar. ¿Dónde está el error?

Editar: utilicé la versión 2.02 desde aquí: 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

Respuesta1

No pretendo entender completamente qué arctimehace y el algoritmo utilizado para calcularlo. Verificando el código fuente de MetaPost, en el mp.warchivo (puede intentar compilar este archivo CWEB en PDF usando cweave, pero algunos _s no tienen el prefijo \_, lo que causa un error al usar TeXed), sección 405, "Las operaciones de longitud de arco y tiempo de arco se basan en un método recursivo función que encuentra la longitud del arco de una spline cúbica dada dz0, dz1, dz2..." y la implementación real es la mp_get_arc_timefunción de la sección 419.

Al leer estas secciones, lo que he entendido es arctimeque se implementa mediante la búsqueda de cero, utilizando la búsqueda binaria en un número flotante (o de punto fijo), para implementar la función inversa de mp_do_arc_test().

Si usa MetaPost en la línea de comando con punto fijo predeterminado de 32 bits (también conocido como escalado), epsilon = 0.00002.

Elhttp://www.tlhiv.org/mppreview/usa double, que establece epsilon = 1.52587890625e-05, y otros sistemas numéricos usan valores similares.

La sección 419 dice,

Si arc0 es mayor que la longitud del arco de una ruta cíclica h, el resultado es un valor de tiempo mayor que la longitud de la ruta.

¿Dónde arc0se proporciona el argumento numérico arctime?

Usando un ejemplo modificado de la pregunta,

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 el sistema numérico escalado predeterminado:

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

Me parece que t=5.92es el valor correcto que se ajusta a esta descripción, y el resultado se puede interpretar usando t = s + l, donde lestá la longitud de la ruta cíclica p, que es longitud 3. Y además se ajusta a la descripción del Manual MetaPost sobre el comportamiento de arctimeque dicearclength subpath (0,t) of p = a

Por lo tanto, es muy probable que el t=2.67...resultado indique un error debido a la adición de diferentes sistemas numéricos.

Respuesta2

Actualización adicional: el equipo de desarrollo ha publicado una solución en el repositorio. Lo saqué de allí y lo construí localmente y se ve bien. Usando el ejemplo pegado a continuación, ahora obtengo esto:

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

y similares de los otros sistemas numéricos. Sin duda, esta solución llegará a las distribuciones estándar a su debido tiempo.

Respondiendo a la pregunta original

El arctimeoperador en MP devuelve el tiempo ten una ruta cuando arclengthla ruta alcanza la longitud deseada en puntos PostScript.

Entonces p, si es un camino y atiene la longitud deseada, entonces arctime a of pda el tiempo ttal que arclength subpath(0, t) of p = a. En todo uso normal, debe asegurarse de que la longitud deseada aesté entre 0 y arclength p.

Pero si el camino pes cíclico, entonces puedes dar una longitud mayor. Esto es similar a la forma en que puede referirse a point 9 of fullcircleetc. Si examina el código fuente, verá que MP proporciona específicamente que la longitud deseada sea mayor que la longitud real de una ruta cíclica. El algoritmo trabaja a lo largo del camino punto por punto y si regresa al comienzo de un ciclo, realiza un cálculo para acortar el resto del proceso (si realmente desea conocer los detalles, puede examinar el código fuente).

La implementación de este cálculo provocó un error con los nuevos sistemas numéricos y que ahora ha sido corregido. Felicitaciones al equipo de desarrollo por una solución rápida.


Actualizar: el equipo de desarrolloconfirmarque esto parece un error debido al uso de matemáticas enteras implícitas en el código fuente de MP.


Esto es realmente un comentario, pero las secciones del archivo de registro son demasiado largas, así que respondo esto.

Con la versión actual de MP, encuentro que su ejemplo da los resultados esperados con el antiguo scaledsistema numérico. Pero resultados "inesperados" con cualquiera de los tres nuevos sistemas. Esto parece algo para informar al equipo de desarrollo.

Si agrego un par de líneas al ejemplo de OP, así:

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

Luego obtengo este archivo de registro si ejecuto mpostel sistema numérico predeterminado:

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

Pero si uso cualquiera de los otros tres sistemas numéricos, obtengo el valor "inesperado" del tprimero informado. Entonces, aparentemente algo sale mal al calcular la arclengthtrayectoria cíclica utilizando los nuevos 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

En mi experiencia con MP, el scaledsistema antiguo casi siempre es mejor. Es posible que el OP desee pedirle al propietario de la vista previa en thiv.org que utilice el sistema numérico predeterminado a menos que se solicite específicamente lo contrario.

información relacionada