Metapost: directionpoint gives unexpected point(?)
Hi, I get sometimes the wrong directionpoint. In the example below it works for all values of direx except between 0 and 90. If I put direx to something in this interval, it seems that the point between cs and cl are chosen. Is there a better way to construct the paths not to get this problem? Or some other way out? /Mikael \starttext \startMPpage[offset=3bp] u:=1cm; path cl,cs,rl,p[]; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl; p[0] = cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle; draw p[0]; drawarrow cs withcolor darkblue; drawarrow cl withcolor darkred; direx=300; z11=directionpoint dir(direx) of p[0]; drawarrow ((-u,0)--(u,0)) rotated direx shifted z11; \stopMPpage \stoptext
Hi,
I was too quick to push send. This must be some rounding error.
Changing the instance fixes the problem. Sorry for the noise.
/Mikael
On Fri, Feb 5, 2021 at 5:48 PM Mikael Sundqvist
Hi,
I get sometimes the wrong directionpoint. In the example below it works for all values of direx except between 0 and 90. If I put direx to something in this interval, it seems that the point between cs and cl are chosen.
Is there a better way to construct the paths not to get this problem? Or some other way out?
/Mikael
\starttext \startMPpage[offset=3bp] u:=1cm; path cl,cs,rl,p[]; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl;
p[0] = cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle;
draw p[0];
drawarrow cs withcolor darkblue; drawarrow cl withcolor darkred;
direx=300; z11=directionpoint dir(direx) of p[0]; drawarrow ((-u,0)--(u,0)) rotated direx shifted z11;
\stopMPpage \stoptext
Hi,
since I already started this thread, I continue here. My metapost code
is still not always working, and I do not understand what is going
wrong. In the example below, I draw two curves of constant width (p1
and p2), one rotated 180 degrees around the origin. Then I draw the
curve (p3), constructed as follows: for each direction (phi), find the
point of p1 and p2 which correspond to it, and add those points. This
should result in a circle, and with the code I paste it does (hooray!
see the file minkowski-good.pdf). BUT, it seems very unstable. If I
change u to 0.5cm instead of 1cm, it breaks down (see
minkowski-bad.pdf). If I loop over more angles phi (say step 2 instead
of step 30), it gets wrong.
Any ideas are welcome.
/Mikael
\starttext
\startMPpage[offset=4bp,instance=doublefun]
u:=1cm;
path p[];
% This defines the reulleaux curves
% p[0] is a "base" reulleaux curve
path cl,cs,rl ;
z0 = (0,6/sqrt(3)*u);
z1 = z0 rotated 120;
cl := (fullcircle scaled 4u) shifted z0;
cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl;
cs := (fullcircle scaled 16u) shifted z1;
cs := cs cutafter point 1/6 along cs;
p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs
rotated 240) .. (cl rotated 240) .. cycle;
% the first curve (darkyellow)
p[1] := p[0] rotated 27 shifted (-10u,2u);
draw p1 withpen pencircle scaled 2bp withcolor darkyellow;
% the second curve (darkblue)
p[2] := p[1] rotated 180;
draw p2 withpen pencircle scaled 2bp withcolor darkblue;
% the minkowski sum (darkred) of the reulleaux curves p1 and p2.
p3 := for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1)
shifted (directionpoint dir(phi) of p2)) .. endfor cycle;
draw p3 withpen pencircle scaled 2bp withcolor darkred;
% We give one direction as example
% These are merely here to show the construction of the curve
% But they also show what is going wrong
direx:=40;
z11=directionpoint dir(direx) of p1;
z22=directionpoint dir(direx) of p2;
p4 = ((-u,0)--(u,0)) rotated direx;
% These arrows should be tangent
drawarrow p4 shifted z11;
drawarrow p4 shifted z22;
drawarrow p4 shifted (z11 shifted z22);
% Draw the parallelogram.
draw origin -- z11 dashed evenly;
draw origin -- z22 dashed evenly;
draw z11 -- (z11 shifted z22) dashed evenly;
draw z22 -- (z11 shifted z22) dashed evenly;
dotlabel.top("$O$",origin);
\stopMPpage
\stoptext
On Fri, Feb 5, 2021 at 5:51 PM Mikael Sundqvist
Hi,
I was too quick to push send. This must be some rounding error. Changing the instance fixes the problem. Sorry for the noise.
/Mikael
On Fri, Feb 5, 2021 at 5:48 PM Mikael Sundqvist
wrote: Hi,
I get sometimes the wrong directionpoint. In the example below it works for all values of direx except between 0 and 90. If I put direx to something in this interval, it seems that the point between cs and cl are chosen.
Is there a better way to construct the paths not to get this problem? Or some other way out?
/Mikael
\starttext \startMPpage[offset=3bp] u:=1cm; path cl,cs,rl,p[]; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl;
p[0] = cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle;
draw p[0];
drawarrow cs withcolor darkblue; drawarrow cl withcolor darkred;
direx=300; z11=directionpoint dir(direx) of p[0]; drawarrow ((-u,0)--(u,0)) rotated direx shifted z11;
\stopMPpage \stoptext
On 2/11/2021 2:45 PM, Mikael Sundqvist wrote:
Hi,
since I already started this thread, I continue here. My metapost code is still not always working, and I do not understand what is going wrong. In the example below, I draw two curves of constant width (p1 and p2), one rotated 180 degrees around the origin. Then I draw the curve (p3), constructed as follows: for each direction (phi), find the point of p1 and p2 which correspond to it, and add those points. This should result in a circle, and with the code I paste it does (hooray! see the file minkowski-good.pdf). BUT, it seems very unstable. If I change u to 0.5cm instead of 1cm, it breaks down (see minkowski-bad.pdf). If I loop over more angles phi (say step 2 instead of step 30), it gets wrong.
Any ideas are welcome. You need help from a metapost-mathematician to answer this (ping ... Alan). Here is a variant that shows you what happens (keep in mind that ".." is not always that useful with that amount of points):
\starttext \startMPdefinitions{doublefun} def FOO(expr u) = path p[]; % This defines the reulleaux curves % p[0] is a "base" reulleaux curve path cl,cs,rl ; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle; % the first curve (darkyellow) % p[1] := p[0] rotated 27 shifted (-10u,2u); p[1] := p[0] rotated 27 shifted (-10u,2u); draw p1 withpen pencircle scaled 2bp withcolor darkyellow; % the second curve (darkblue) p[2] := p[1] rotated 180; draw p2 withpen pencircle scaled 2bp withcolor darkblue; % the minkowski sum (darkred) of the reulleaux curves p1 and p2. % p3 := for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) % shifted (directionpoint dir(phi) of p2)) .. endfor cycle; % draw p3 withpen pencircle scaled 2bp withcolor darkred; % for phi=0 step 30 until 360: % draw (directionpoint dir(phi) of p1) withpen pencircle scaled 4bp withcolor darkgreen; % draw (directionpoint dir(phi) of p2) withpen pencircle scaled 4bp withcolor darkmagenta; % endfor ; drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p1) -- endfor cycle withpen pencircle scaled 1bp withcolor darkgreen; drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p2) -- endfor cycle withpen pencircle scaled 1bp withcolor darkmagenta; drawarrow for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) shifted (directionpoint dir(phi) of p2)) -- endfor cycle % .5[directionpoint dir(phi) of p1, directionpoint dir(phi) of p2] -- endfor cycle withpen pencircle scaled 1bp withcolor darkred; % We give one direction as example % These are merely here to show the construction of the curve % But they also show what is going wrong direx:=40; z11=directionpoint dir(direx) of p1; z22=directionpoint dir(direx) of p2; p4 = ((-u,0)--(u,0)) rotated direx; % These arrows should be tangent drawarrow p4 shifted z11; drawarrow p4 shifted z22; drawarrow p4 shifted (z11 shifted z22); % Draw the parallelogram. draw origin -- z11 dashed evenly; draw origin -- z22 dashed evenly; draw z11 -- (z11 shifted z22) dashed evenly; draw z22 -- (z11 shifted z22) dashed evenly; % dotlabel.top("$O$",origin); enddef ; \stopMPdefinitions \startMPpage[offset=4bp,instance=doublefun] FOO(1cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.8cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.5cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] draw image (FOO(1/20)) scaled 5cm withpen pencircle scaled 1bp; \stopMPpage \stoptext You probably end up in the 1bp resolutions ... or something around the origin ... so maybe just calculate large and scale the result to what you want. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Thanks for your investigation and extended example!
So, if I understand it correctly, the problem occurs where the
different circles are glued together with the .. construction.
I will wait to see if Alan or somebody else has an idea of a nice
solution to the problem.
/Mikael
On Thu, Feb 11, 2021 at 3:54 PM Hans Hagen
On 2/11/2021 2:45 PM, Mikael Sundqvist wrote:
Hi,
since I already started this thread, I continue here. My metapost code is still not always working, and I do not understand what is going wrong. In the example below, I draw two curves of constant width (p1 and p2), one rotated 180 degrees around the origin. Then I draw the curve (p3), constructed as follows: for each direction (phi), find the point of p1 and p2 which correspond to it, and add those points. This should result in a circle, and with the code I paste it does (hooray! see the file minkowski-good.pdf). BUT, it seems very unstable. If I change u to 0.5cm instead of 1cm, it breaks down (see minkowski-bad.pdf). If I loop over more angles phi (say step 2 instead of step 30), it gets wrong.
Any ideas are welcome. You need help from a metapost-mathematician to answer this (ping ... Alan). Here is a variant that shows you what happens (keep in mind that ".." is not always that useful with that amount of points):
\starttext \startMPdefinitions{doublefun}
def FOO(expr u) =
path p[];
% This defines the reulleaux curves % p[0] is a "base" reulleaux curve path cl,cs,rl ; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle;
% the first curve (darkyellow) % p[1] := p[0] rotated 27 shifted (-10u,2u); p[1] := p[0] rotated 27 shifted (-10u,2u); draw p1 withpen pencircle scaled 2bp withcolor darkyellow; % the second curve (darkblue) p[2] := p[1] rotated 180; draw p2 withpen pencircle scaled 2bp withcolor darkblue;
% the minkowski sum (darkred) of the reulleaux curves p1 and p2. % p3 := for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) % shifted (directionpoint dir(phi) of p2)) .. endfor cycle; % draw p3 withpen pencircle scaled 2bp withcolor darkred;
% for phi=0 step 30 until 360: % draw (directionpoint dir(phi) of p1) withpen pencircle scaled 4bp withcolor darkgreen; % draw (directionpoint dir(phi) of p2) withpen pencircle scaled 4bp withcolor darkmagenta; % endfor ;
drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p1) -- endfor cycle withpen pencircle scaled 1bp withcolor darkgreen; drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p2) -- endfor cycle withpen pencircle scaled 1bp withcolor darkmagenta;
drawarrow for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) shifted (directionpoint dir(phi) of p2)) -- endfor cycle % .5[directionpoint dir(phi) of p1, directionpoint dir(phi) of p2] -- endfor cycle withpen pencircle scaled 1bp withcolor darkred;
% We give one direction as example % These are merely here to show the construction of the curve % But they also show what is going wrong
direx:=40;
z11=directionpoint dir(direx) of p1; z22=directionpoint dir(direx) of p2;
p4 = ((-u,0)--(u,0)) rotated direx;
% These arrows should be tangent drawarrow p4 shifted z11; drawarrow p4 shifted z22; drawarrow p4 shifted (z11 shifted z22);
% Draw the parallelogram. draw origin -- z11 dashed evenly; draw origin -- z22 dashed evenly; draw z11 -- (z11 shifted z22) dashed evenly; draw z22 -- (z11 shifted z22) dashed evenly;
% dotlabel.top("$O$",origin); enddef ; \stopMPdefinitions
\startMPpage[offset=4bp,instance=doublefun] FOO(1cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.8cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.5cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] draw image (FOO(1/20)) scaled 5cm withpen pencircle scaled 1bp; \stopMPpage \stoptext
You probably end up in the 1bp resolutions ... or something around the origin ... so maybe just calculate large and scale the result to what you want.
Hans
----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Hi,
On 11 Feb 2021, at 17:41, Mikael Sundqvist
wrote: Thanks for your investigation and extended example!
So, if I understand it correctly, the problem occurs where the different circles are glued together with the .. construction.
Took me a while to get it, but the problem is the definition of p0: p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle; Here are cs and cl after your earlier definition: cs := (141.73224999999996,-49.097491614210789) ..(75.312386775380347,111.25424516116959) ..(28.347427842053655,147.2925755432174); cl := (28.346108531095332,147.29283827977969) ..(0,154.88788322842163) ..(-28.346108531095332,147.29283827977969); Note how the last point of cs and the first point of cl are nearly the same. When you combine these bits into p0, p0 becomes a cyclic path with 18 points (where you really want/need only 12 points). The micro-segments between these nearly-identical paths are the problem. At smaller u values the differences between the points become zero, and the directionpoint of a path of length zero is mathematically undefined. I do not know a quick generic solution off hand, but that is what the issue is. Best wishes, Taco
Hi Taco,
thanks, from your observation and the way I build the paths, I found
out that I can avoid the problem by shortening the paths I join just
slightly:
cl := (fullcircle scaled 4u) shifted z0;
cl := cl cutbefore point (1/6+epsilon) along cl cutafter point
(2/6-epsilon) along cl;
cs := (fullcircle scaled 16u) shifted z1;
cs := cs cutafter point (1/6-epsilon) along cs;
and indeed, it works here now, with different values of the scale u,
and it seems more stable.
/Mikael
PS I found out that eps and epsilon both worked, and I do not see in
the metafun manual if there is a difference.
On Fri, Feb 12, 2021 at 9:35 AM Taco Hoekwater
Hi,
On 11 Feb 2021, at 17:41, Mikael Sundqvist
wrote: Thanks for your investigation and extended example!
So, if I understand it correctly, the problem occurs where the different circles are glued together with the .. construction.
Took me a while to get it, but the problem is the definition of p0:
p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle;
Here are cs and cl after your earlier definition:
cs := (141.73224999999996,-49.097491614210789) ..(75.312386775380347,111.25424516116959) ..(28.347427842053655,147.2925755432174);
cl := (28.346108531095332,147.29283827977969) ..(0,154.88788322842163) ..(-28.346108531095332,147.29283827977969);
Note how the last point of cs and the first point of cl are nearly the same. When you combine these bits into p0, p0 becomes a cyclic path with 18 points (where you really want/need only 12 points).
The micro-segments between these nearly-identical paths are the problem. At smaller u values the differences between the points become zero, and the directionpoint of a path of length zero is mathematically undefined.
I do not know a quick generic solution off hand, but that is what the issue is.
Best wishes, Taco
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
On 12 Feb 2021, at 10:31, Mikael Sundqvist
wrote: Hi Taco,
thanks, from your observation and the way I build the paths, I found out that I can avoid the problem by shortening the paths I join just slightly:
cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point (1/6+epsilon) along cl cutafter point (2/6-epsilon) along cl; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point (1/6-epsilon) along cs;
and indeed, it works here now, with different values of the scale u, and it seems more stable.
Here is a quick hack I wrote that does the cleanup in a postprocessing stage. It is not very generic or clever, but it works for your case: def clean_path(suffix p) = begingroup; save q,precontrols,postcontrols,points, skip, i,j; boolean skip; pair precontrols[],postcontrols[],points[] ; j := 0; for i = 0 upto length p: skip := false; if abs(xpart point i of p - xpart point i+1 of p)<0.01: if abs(ypart point i of p - ypart point i+1 of p)<0.01: skip := true; fi fi if not skip: points[j] := point i of p; postcontrols[j] := postcontrol i of p; precontrols[j+1] := precontrol i+1 of p; j := j + 1; fi endfor; if abs(xpart point 0 of p - xpart point length p of p)<0.01: if abs(ypart point 0 of p - ypart point length p of p)<0.01: j := j - 1; fi fi p := for i=0 upto j-1: points[i] .. controls postcontrols[i] and precontrols[i+1] .. endfor cycle; endgroup; enddef; show p0; clean_path(p0); show p0;
PS I found out that eps and epsilon both worked, and I do not see in the metafun manual if there is a difference.
The original intent was for eps to be just a ’small enough value that a human will not notice it’ where epsilon is intended as ’the smallest representable value’. Neither really work that way because depending on how you use metapost eps can be quite visible (especially in non-scaled number systems) and (more importantly) in the new non-scaled number systems epsilon cannot really be the smallest representable value for numerical and practical reasons. So in reality, we always use these definitions: eps := .00049 ; % this is a pretty small positive number epsilon := 1/256/256 Best wishes, Taco — Taco Hoekwater E: taco@bittext.nl genderfluid (all pronouns)
On 2/12/2021 9:35 AM, Taco Hoekwater wrote:
Hi,
On 11 Feb 2021, at 17:41, Mikael Sundqvist
wrote: Thanks for your investigation and extended example!
So, if I understand it correctly, the problem occurs where the different circles are glued together with the .. construction.
Took me a while to get it, but the problem is the definition of p0:
p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle;
Here are cs and cl after your earlier definition:
cs := (141.73224999999996,-49.097491614210789) ..(75.312386775380347,111.25424516116959) ..(28.347427842053655,147.2925755432174);
cl := (28.346108531095332,147.29283827977969) ..(0,154.88788322842163) ..(-28.346108531095332,147.29283827977969);
Note how the last point of cs and the first point of cl are nearly the same. When you combine these bits into p0, p0 becomes a cyclic path with 18 points (where you really want/need only 12 points).
The micro-segments between these nearly-identical paths are the problem. At smaller u values the differences between the points become zero, and the directionpoint of a path of length zero is mathematically undefined.
I do not know a quick generic solution off hand, but that is what the issue is. Brilliant, as usual. So, now I can kick in with the dirty hackery (can be some proper thing but that's for later):
\starttext \startluacode function mp.foo() local p = mp.scan.path() local r = math.round local d = 100000 for i=1,#p do local pi = p[i] pi[1] = r(pi[1] * d) / d pi[2] = r(pi[2] * d) / d end local x1 = r(p[1][1]) local y1 = r(p[1][2]) local n = 1 local t = { p[1], cycle = p.cycle } for i=2,#p do local x2 = r(p[i][1]) local y2 = r(p[i][2]) if x1 ~= x2 or y1 ~= y2 then n = n + 1 t[n] = p[i] x1 = x2 y1 = y2 end end -- inspect(t) mp.inject.path(t) end \stopluacode \startMPdefinitions{doublefun} def FOO(expr u) = path p[]; % This defines the reulleaux curves % p[0] is a "base" reulleaux curve path cl,cs,rl ; z0 = (0,6/sqrt(3)*u); z1 = z0 rotated 120; cl := (fullcircle scaled 4u) shifted z0; cl := cl cutbefore point 1/6 along cl cutafter point 2/6 along cl; cs := (fullcircle scaled 16u) shifted z1; cs := cs cutafter point 1/6 along cs; p[0] := cs .. cl .. (cs rotated 120) .. (cl rotated 120) .. (cs rotated 240) .. (cl rotated 240) .. cycle; % p[0] := runscript("mp.foo()") p[0]; % the first curve (darkyellow) % p[1] := p[0] rotated 27 shifted (-10u,2u); p[1] := p[0] rotated 27 shifted (-10u,2u); draw p1 withpen pencircle scaled 2bp withcolor darkyellow; % the second curve (darkblue) p[2] := p[1] rotated 180; draw p2 withpen pencircle scaled 2bp withcolor darkblue; if true : p[1] := runscript("mp.foo()") p[1]; p[2] := runscript("mp.foo()") p[2]; p3 := for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) shifted (directionpoint dir(phi) of p2)) .. endfor cycle; draw p3 withpen pencircle scaled 2bp withcolor darkred; else : drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p1) -- endfor cycle withpen pencircle scaled 1bp withcolor darkgreen; drawarrow for phi=0 step 30 until 360: (directionpoint dir(phi) of p2) -- endfor cycle withpen pencircle scaled 1bp withcolor darkmagenta; drawarrow for phi=0 step 30 until 360: ((directionpoint dir(phi) of p1) shifted (directionpoint dir(phi) of p2)) -- endfor cycle withpen pencircle scaled 1bp withcolor darkred; fi ; % We give one direction as example % These are merely here to show the construction of the curve % But they also show what is going wrong direx:=40; z11=directionpoint dir(direx) of p1; z22=directionpoint dir(direx) of p2; p4 = ((-u,0)--(u,0)) rotated direx; % These arrows should be tangent drawarrow p4 shifted z11; drawarrow p4 shifted z22; drawarrow p4 shifted (z11 shifted z22); % Draw the parallelogram. draw origin -- z11 dashed evenly; draw origin -- z22 dashed evenly; draw z11 -- (z11 shifted z22) dashed evenly; draw z22 -- (z11 shifted z22) dashed evenly; enddef ; \stopMPdefinitions \startMPpage[offset=4bp,instance=doublefun] FOO(1cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.8cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.5cm); \stopMPpage \startMPpage[offset=4bp,instance=doublefun] FOO(.2cm); \stopMPpage \stoptext ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Hi, Like this: metapost.registerscript("scrutenized", function() local p = mp.scan.path() local r = math.round local d = 10^mp.scan.numeric() for i=1,#p do local pi = p[i] pi[1] = r(pi[1] * d) / d pi[2] = r(pi[2] * d) / d end local x1 = r(p[1][1]) local y1 = r(p[1][2]) local n = 1 local t = { p[1], cycle = p.cycle } for i=2,#p do local pi = p[i] local x2 = r(pi[1]) local y2 = r(pi[2]) if x1 ~= x2 or y1 ~= y2 then n = n + 1 t[n] = p[i] x1 = x2 y1 = y2 end end mp.inject.path(t) end) \stopluacode \startMPdefinitions{doublefun} newscriptindex mfid_scrutenized ; mfid_scrutenized := scriptindex "scrutenized" ; primarydef p scrutenized n = runscript mfid_scrutenized p n enddef ; \stopMPdefinitions and then p[1] := p[1] scrutenized 5 ; % 5 decimals p[2] := p[2] scrutenized 5 ; % 5 decimals Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
participants (3)
-
Hans Hagen
-
Mikael Sundqvist
-
Taco Hoekwater