ntg-context - mailing list for ConTeXt users
 help / color / mirror / Atom feed
* Metapost: directionpoint gives unexpected point(?)
@ 2021-02-05 16:48 Mikael Sundqvist
  2021-02-05 16:51 ` Mikael Sundqvist
  0 siblings, 1 reply; 10+ messages in thread
From: Mikael Sundqvist @ 2021-02-05 16:48 UTC (permalink / raw)
  To: mailing list for ConTeXt users

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-05 16:48 Metapost: directionpoint gives unexpected point(?) Mikael Sundqvist
@ 2021-02-05 16:51 ` Mikael Sundqvist
  2021-02-11 13:45   ` Mikael Sundqvist
  0 siblings, 1 reply; 10+ messages in thread
From: Mikael Sundqvist @ 2021-02-05 16:51 UTC (permalink / raw)
  To: mailing list for ConTeXt users

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 <mickep@gmail.com> 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
___________________________________________________________________________________
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
___________________________________________________________________________________

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-05 16:51 ` Mikael Sundqvist
@ 2021-02-11 13:45   ` Mikael Sundqvist
  2021-02-11 14:54     ` Hans Hagen
  0 siblings, 1 reply; 10+ messages in thread
From: Mikael Sundqvist @ 2021-02-11 13:45 UTC (permalink / raw)
  To: mailing list for ConTeXt users

[-- Attachment #1: Type: text/plain, Size: 3751 bytes --]

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 <mickep@gmail.com> wrote:
>
> 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 <mickep@gmail.com> 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

[-- Attachment #2: minkowski-good.pdf --]
[-- Type: application/pdf, Size: 5536 bytes --]

[-- Attachment #3: minkowski-bad.pdf --]
[-- Type: application/pdf, Size: 5399 bytes --]

[-- Attachment #4: Type: text/plain, Size: 493 bytes --]

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-11 13:45   ` Mikael Sundqvist
@ 2021-02-11 14:54     ` Hans Hagen
  2021-02-11 16:41       ` Mikael Sundqvist
  0 siblings, 1 reply; 10+ messages in thread
From: Hans Hagen @ 2021-02-11 14:54 UTC (permalink / raw)
  To: mailing list for ConTeXt users, Mikael Sundqvist

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-11 14:54     ` Hans Hagen
@ 2021-02-11 16:41       ` Mikael Sundqvist
  2021-02-12  8:35         ` Taco Hoekwater
  0 siblings, 1 reply; 10+ messages in thread
From: Mikael Sundqvist @ 2021-02-11 16:41 UTC (permalink / raw)
  To: Hans Hagen; +Cc: mailing list for ConTeXt users

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 <j.hagen@xs4all.nl> wrote:
>
> 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
> -----------------------------------------------------------------
___________________________________________________________________________________
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
___________________________________________________________________________________

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-11 16:41       ` Mikael Sundqvist
@ 2021-02-12  8:35         ` Taco Hoekwater
  2021-02-12  9:31           ` Mikael Sundqvist
  2021-02-12  9:53           ` Hans Hagen
  0 siblings, 2 replies; 10+ messages in thread
From: Taco Hoekwater @ 2021-02-12  8:35 UTC (permalink / raw)
  To: mailing list for ConTeXt users

Hi,

> On 11 Feb 2021, at 17:41, Mikael Sundqvist <mickep@gmail.com> 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
___________________________________________________________________________________

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-12  8:35         ` Taco Hoekwater
@ 2021-02-12  9:31           ` Mikael Sundqvist
  2021-02-12  9:55             ` Taco Hoekwater
  2021-02-12  9:53           ` Hans Hagen
  1 sibling, 1 reply; 10+ messages in thread
From: Mikael Sundqvist @ 2021-02-12  9:31 UTC (permalink / raw)
  To: mailing list for ConTeXt users

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 <taco@bittext.nl> wrote:
>
> Hi,
>
> > On 11 Feb 2021, at 17:41, Mikael Sundqvist <mickep@gmail.com> 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
> ___________________________________________________________________________________
___________________________________________________________________________________
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
___________________________________________________________________________________

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-12  8:35         ` Taco Hoekwater
  2021-02-12  9:31           ` Mikael Sundqvist
@ 2021-02-12  9:53           ` Hans Hagen
  2021-02-12 10:03             ` Hans Hagen
  1 sibling, 1 reply; 10+ messages in thread
From: Hans Hagen @ 2021-02-12  9:53 UTC (permalink / raw)
  To: Taco Hoekwater, mailing list for ConTeXt users

On 2/12/2021 9:35 AM, Taco Hoekwater wrote:
> Hi,
> 
>> On 11 Feb 2021, at 17:41, Mikael Sundqvist <mickep@gmail.com> 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
-----------------------------------------------------------------
___________________________________________________________________________________
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
___________________________________________________________________________________

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-12  9:31           ` Mikael Sundqvist
@ 2021-02-12  9:55             ` Taco Hoekwater
  0 siblings, 0 replies; 10+ messages in thread
From: Taco Hoekwater @ 2021-02-12  9:55 UTC (permalink / raw)
  To: mailing list for ConTeXt users



> On 12 Feb 2021, at 10:31, Mikael Sundqvist <mickep@gmail.com> 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)



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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Metapost: directionpoint gives unexpected point(?)
  2021-02-12  9:53           ` Hans Hagen
@ 2021-02-12 10:03             ` Hans Hagen
  0 siblings, 0 replies; 10+ messages in thread
From: Hans Hagen @ 2021-02-12 10:03 UTC (permalink / raw)
  To: Taco Hoekwater, mailing list for ConTeXt users

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-02-12 10:03 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-05 16:48 Metapost: directionpoint gives unexpected point(?) Mikael Sundqvist
2021-02-05 16:51 ` Mikael Sundqvist
2021-02-11 13:45   ` Mikael Sundqvist
2021-02-11 14:54     ` Hans Hagen
2021-02-11 16:41       ` Mikael Sundqvist
2021-02-12  8:35         ` Taco Hoekwater
2021-02-12  9:31           ` Mikael Sundqvist
2021-02-12  9:55             ` Taco Hoekwater
2021-02-12  9:53           ` Hans Hagen
2021-02-12 10:03             ` Hans Hagen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).