On Wed, 19 Sep 2018 11:18:30 +1200
Henri Menke
On 18/09/18 21:23, Henri Menke wrote:
On 9/18/18 7:57 PM, Hans Hagen wrote:
On 9/16/2018 10:28 AM, Henri Menke wrote:
Dear list,
I want to draw paths between points which are bent by a certain angle. The code in the MWE below works well but I was thinking that the expert here can surely improve it and suggest a nicer syntax. looks like a challenge for Alan ... isn't it also a bit 3d (2.5d)?
I wasn't thinking about a 3D application here, just a little bend on the path to go around other elements in my drawing without having to think about explicit control points (like the second example in my original post). In the meantime I have improved the defintion of the macro to avoid double computation of the angle:
vardef bend(expr a,b,phi) = save x ; x := angle(b-a) ; a{dir(x+phi)} .. {dir(x-phi)}b enddef ;
So currently the applied syntax is
drawarrow bend(z1, z2, 30) ;
However, I would prefer something like
drawarrow z1 bend(30) z2 ;
I'm not sure whether this is possible though. Actually I'm reading the MetaPost manual right know because my MP skills are rather poor.
I think I got it now. Not sure whether “bend” should be primary or something else.
\startMPdefinitions primarydef a bend phi = do_bend(a,phi) enddef ;
vardef do_bend(expr a, phi) expr b = save x ; x := angle(b-a) ; a{dir(x+phi)} .. {dir(x-phi)}b enddef ; \stopMPdefinitions
\starttext
\startMPpage z1 = (-.5cm,1cm) ; z2 = (1cm,3cm) ;
for phi = 0 step 5 until 360: draw z1 bend(phi) z2 withcolor (phi/360)[red,blue] ; endfor ; \stopMPpage
% Possible use case:
\startMPpage[offset=1cm] z1 = (-.5cm,1cm) ; z2 = (1cm,3cm) ; draw z1 -- z2 ; dotlabel.lft("$-$", z1) ; dotlabel.lft("$+$", z2) ;
path p; p := z1 bend(-30) z2 ; drawdblarrow p withcolor blue ; label.lrt(textext("$\Delta$"),point .5 along p) withcolor blue ; \stopMPpage
\stoptext
Henri, 1. I added a sanity test (angle(origin) is undefined); 2. it is probably more efficient to calculate the angle twice than to allocate storage; 3. primary b; 4. then I created the variant arc (as in a bow) taking a delta (the tangent of an angle). Alan \startMPdefinitions primarydef a bend phi = do_bend(a,phi) enddef ; vardef do_bend(expr a, phi) primary b = if abs(a-b)=0 : a else : (a{dir(angle(b-a)+phi)} .. {dir(angle(b-a)-phi)}b) fi enddef ; primarydef a arc delta = do_arc(a,delta) enddef ; vardef do_arc(expr a,delta) primary b = if abs(a-b)=0 : a else : (a .. unitvector direction .5 of (a--b) rotated 90 scaled delta * arclength (a--b) shifted .5[a,b] .. b) fi enddef ; \stopMPdefinitions \starttext \startMPpage z1 = (-.5cm,1cm) ; z2 = (1cm,3cm) ; for phi = 0 step 5 until 360: draw z1 bend phi z2 withcolor (phi/360)[red,blue] ; endfor ; \stopMPpage \startMPpage z1 = (-.5cm,1cm) ; z2 = (1cm,3cm) ; for delta = -1 step .1 until 1: draw z1 arc delta z2 withcolor ((delta+1)/2)[red,blue] ; endfor ; \stopMPpage % Possible use case: \startMPpage[offset=1cm] z1 = (-.5cm,1cm) ; z2 = (1cm,3cm) ; draw z1 -- z2 ; dotlabel.lft("$-$", z1) ; dotlabel.lft("$+$", z2) ; path p; p := z1 bend(-30) z2 ; drawdblarrow p withcolor blue ; label.lrt(textext("$\Delta$"),point .5 along p) withcolor blue ; \stopMPpage \stoptext