[metapost] straight lines vs. curves (SVG)

Boguslaw Jackowski jacko at bop.com.pl
Mon Apr 27 09:24:03 CEST 2009


Hi,

this topic was already discussed on here a few years ago,
but I thought that recalling some remarks would be in place.

To me, it seems convenient to represent a line segment from A to B as:

    A .. controls A and B .. B

It is easy to check the property of being a line, no additional
flags are needed etc. The only problem is with the direction in nodes; 
post and precontrol point are no longer useful. In our plain_ex macros 
(used mainly for creating fonts) we use the following definitions:

vardef gendir expr t of p =
  predir t of p + postdir t of p % |direction|-compatible definition
enddef;

vardef predir expr t of p =
  save a_,b_,c_,d_,s_,t_; pair a_,b_,c_,d_; path s_; t_:=t;
  if not cycle p: if t<0: t_:=0; elseif t>length(p): t_:=length(p); fi fi
   s_=subpath (ceiling t_-1,t_) of p;
   a_=point 0 of s_;
   b_=postcontrol 0 of s_; % |b_<>postcontrol t-1 of p| for |t=0|
   c_=precontrol 1 of s_;
   d_=point 1 of s_;
   if d_<>c_:     d_-c_
   elseif d_<>b_: d_-b_
   elseif d_<>a_: d_-a_
   else:       (0,0)
  fi
enddef;

vardef postdir expr t of p =
  save a_,b_,c_,d_,s_,t_; pair a_,b_,c_,d_; path s_; t_:=t;
  if not cycle p: if t<0: t_:=0; elseif t>length(p): t_:=length(p); fi fi
   s_=subpath (t_,floor t_+1) of p;
   a_=point 0 of s_;
   b_=postcontrol 0 of s_;
   c_=precontrol 1 of s_; % |c_<>precontrol t+1 of p| for |t=length p|
   d_=point 1 of s_;
   if a_<>b_:     b_-a_
   elseif a_<>c_: c_-a_
   elseif a_<>d_: d_-a_
   else:       (0,0)
  fi
enddef;

One might have thought about including them as built in functions...

Cheers -- Jacko

Ps. Here you have the argumentation why the above macros are expected 
to work -- it is an excerpt from the plain_ex documentation:

% The definitions of |postdir| and |predir| are
% based on the following observation, being the consequence
% of the de~l'H\^ospital's rule: consider a~B\'ezier segment
% |a .. controls b and c .. d|; normally, the vector $\vec{ab}$
% determines the ``post'' direction at node~$a$; if $b$
% coincides with $a$, then the vector $\vec{ac}$ determines
% the direction; if also $c$ coincides coincides with~$a$,
% then the last resort is the vector $\vec{ad}$; if even $d$
% coincides with~$a$, the B\'ezier segment is degenerated,
% and can be removed (a~similar argumentation can be provided
% for the ``pre'' direction at node~$d$).


-- 
BOP s. c.
ul. Bora-Komorowskiego 24, 80-377 Gdansk, Poland
tel. (+48 58) 553 46 59,  fax (+48 58) 511 03 81
bop at bop.com.pl, http://www.bop.com.pl


More information about the metapost mailing list