[metapost] Re: all intersections between two paths

Boguslaw Jackowski bop at bop.com.pl
Sun Jan 16 19:12:28 CET 2005


LarryS> PS.  Who can offer MF substitutes for the MP functions 'ulcorner' 
LarryS> and 'lrcorner' that I use for 'autosizing'.

LaurenceF> How about (0, h) and (w, -d)?

I understand that the argument to the macro that Larry needs should be
a curve (or a set of curves), not a glyph with a complete metric.

Below there is the definition of the `find_BB' procedure that finds lower
left and upper right coordinates (xl_crd, yl_crd, xh_crd, and yh_crd,
respectively) for a given set of curves.

A sample usage:

   p:=unitsquare shifted (-1/2, -1/2) rotated 45;
   find_BB p; show (xl_crd,yl_crd), (xh_crd,yh_crd);

Cheers -- Jacko

Ps. I believe that I talked about the problem of the finding
    of the bounding box of a curve using MF during the EuroTeX/TUG
    meeting in 1994 (Sobieszewo, Poland).

% --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
% |xl|, |yl|, |xh|, and |yh| can likely be used in a program, hence
% longer names: |xl_crd|, |yl_crd|, |xh_crd|, and |yh_crd|, respectively
def find_BB text t =
 for CC_:=t: % |t| may be empty
  if unknown xl_crd: xl_crd=yl_crd=-xh_crd=-yh_crd=infinity; fi
  update_BC(CC_)(xl_crd,yl_crd,xh_crd,yh_crd);
 endfor
enddef;
% ---
vardef update_BC(expr C)(suffix xl,yl,xh,yh) =
% updates variables |xl|, |yl|, |xh|, |yh| by finding extremal points
% of a B\'ezier curve |C|
 if xl>xpart(point 0 of C): xl:=xpart(point 0 of C); fi
 if xh<xpart(point 0 of C): xh:=xpart(point 0 of C); fi
 if yl>ypart(point 0 of C): yl:=ypart(point 0 of C); fi
 if yh<ypart(point 0 of C): yh:=ypart(point 0 of C); fi
 for tt_:=0 upto length(C)-1:
  update_BB(subpath (tt_,tt_+1) of C,xl,yl,xh,yh);
 endfor
enddef;
% ---
vardef update_BB(expr B) (suffix xl,yl,xh,yh) =
% updates variables |xl|, |yl|, |xh|, |yh| by finding extremal points
% of a B\'ezier segment |B|; the |point 0 of B| is not taken into account
 save Bx_,By_,ta_,tb_,vv_; path Bx_, By_; numeric ta_,tb_,vv_;
%
 Bx_=(0,xpart(point 0 of B))
  ..controls
   (0,xpart(postcontrol 0 of B)) and (1000,xpart(precontrol 1 of B))
  ..(1000,xpart(point 1 of B));
 By_=(0,ypart(point 0 of B))
  ..controls
   (0,ypart(postcontrol 0 of B)) and (1000,ypart(precontrol 1 of B))
  ..(1000,ypart(point 1 of B));
%
 ta_:=directiontime right of Bx_;
 if ta_>0:
  vv_:=ypart (point ta_ of Bx_);
  if vv_<xl: xl:=vv_; fi\\ if vv_>xh: xh:=vv_; fi
  tb_:=directiontime right of subpath (ta_+eps,1) of Bx_;
  if tb_>=0:
   vv_:=ypart (point tb_ of (subpath (ta_+eps,1) of Bx_));
   if vv_<xl: xl:=vv_; fi\\ if vv_>xh: xh:=vv_; fi
  fi
 fi
 vv_:=ypart (point 1 of Bx_); if vv_<xl: xl:=vv_; fi\\ if vv_>xh: xh:=vv_; fi
%
 ta_:=directiontime right of By_;
 if ta_>0:
  vv_:=ypart (point ta_ of By_);
  if vv_<yl: yl:=vv_; fi\\ if vv_>yh: yh:=vv_; fi
  tb_:=directiontime right of subpath (ta_+eps,1) of By_;
  if tb_>=0:
   vv_:=ypart (point tb_ of (subpath (ta_+eps,1) of By_));
   if vv_<yl: yl:=vv_; fi\\ if vv_>yh: yh:=vv_; fi
  fi
 fi
 vv_:=ypart (point 1 of By_); if vv_<yl: yl:=vv_; fi\\ if vv_>yh: yh:=vv_; fi
enddef;
% ---
def reset_BB =
 xl_crd:=whatever; yl_crd:=whatever; xh_crd:=whatever; yh_crd:=whatever;
enddef;
% --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---


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