diff options
Diffstat (limited to 'metapost/context/base/mpxl/mp-tool.mpxl')
-rw-r--r-- | metapost/context/base/mpxl/mp-tool.mpxl | 495 |
1 files changed, 425 insertions, 70 deletions
diff --git a/metapost/context/base/mpxl/mp-tool.mpxl b/metapost/context/base/mpxl/mp-tool.mpxl index 6593b5e9a..e448ebb5a 100644 --- a/metapost/context/base/mpxl/mp-tool.mpxl +++ b/metapost/context/base/mpxl/mp-tool.mpxl @@ -326,26 +326,53 @@ enddef ; % let push_boundingbox = pushboundingbox ; % downward compatible % let pop_boundingbox = popboundingbox ; % downward compatible -vardef boundingbox primary p = - if (path p) or (picture p) : - llcorner p -- lrcorner p -- urcorner p -- ulcorner p - else : - origin - fi -- cycle -enddef; +% vardef boundingbox primary p = +% if (path p) or (picture p) : +% llcorner p -- lrcorner p -- urcorner p -- ulcorner p +% else : +% origin +% fi -- cycle +% enddef; + +% vardef boundingbox primary p = +% if (path p) or (picture p) : +% save a, b ; pair a, b ; a := llcorner p ; b:= urcorner p ; +% a -- (xpart b, ypart a) -- b -- (xpart a, ypart b) +% else : +% origin +% fi -- cycle +% enddef; + +% vardef innerboundingbox primary p = +% top rt llcorner p -- +% top lft lrcorner p -- +% bot lft urcorner p -- +% bot rt ulcorner p -- cycle +% enddef; + +% vardef outerboundingbox primary p = +% bot lft llcorner p -- +% bot rt lrcorner p -- +% top rt urcorner p -- +% top lft ulcorner p -- cycle +% enddef; + +let boundingbox = corners ; vardef innerboundingbox primary p = - top rt llcorner p -- - top lft lrcorner p -- - bot lft urcorner p -- - bot rt ulcorner p -- cycle + save b ; path b ; b := corners p ; + top rt point 0 of b -- + top lft point 1 of b -- + bot lft point 2 of b -- + bot rt point 3 of b -- cycle enddef; vardef outerboundingbox primary p = - bot lft llcorner p -- - bot rt lrcorner p -- - top rt urcorner p -- - top lft ulcorner p -- cycle + save b ; path b ; b := corners p ; + bot lft point 0 of b -- + bot rt point 1 of b -- + top rt point 2 of b -- + top lft point 3 of b -- cycle enddef; % def inner_boundingbox = innerboundingbox enddef ; @@ -369,11 +396,12 @@ enddef; vardef boundingradius primary p = if picture p : + pair c ; c := -center p; max( - abs((llcorner p) shifted -center p), - abs((lrcorner p) shifted -center p), - abs((urcorner p) shifted -center p), - abs((ulcorner p) shifted -center p) + abs((llcorner p) shifted c), + abs((lrcorner p) shifted c), + abs((urcorner p) shifted c), + abs((ulcorner p) shifted c) ) elseif pen p : boundingradius image(draw makepath p ;) @@ -715,30 +743,196 @@ enddef ; %D A few normalizing macros: +% primarydef p xsized w = +% (p if (bbwidth (p) > 0) and (w > 0) : scaled (w/bbwidth (p)) fi) +% enddef ; +% primarydef p xsized w = +% begingroup +% save b, l ; path b; +% b := corners p ; +% l := xpart point 1 of b - xpart point 0 of b ; +% (p if (l > 0) and (w > 0) : scaled (w/l) fi) +% endgroup +% enddef ; primarydef p xsized w = - (p if (bbwidth (p) > 0) and (w > 0) : scaled (w/bbwidth (p)) fi) + begingroup + save r, l ; pair r; + r := xrange p ; + l := ypart r - xpart r ; + (p if (l > 0) and (w > 0) : scaled (w/l) fi) + endgroup enddef ; +% primarydef p ysized h = +% (p if (bbheight(p) > 0) and (h > 0) : scaled (h/bbheight(p)) fi) +% enddef ; +% primarydef p ysized h = +% begingroup +% save b, l ; path b; +% b := corners p ; +% l := ypart point 2 of b - ypart point 1 of b ; +% (p if (l > 0) and (h > 0) : scaled (h/l) fi) +% endgroup +% enddef ; primarydef p ysized h = - (p if (bbheight(p) > 0) and (h > 0) : scaled (h/bbheight(p)) fi) + begingroup + save r, l ; pair r ; + r := yrange p ; + l := ypart r - xpart r ; + (p if (l > 0) and (h > 0) : scaled (h/l) fi) + endgroup enddef ; -primarydef p xysized s = +% primarydef p xysized s = % a one step transform might be faster +% begingroup +% save wh, w, h ; pair wh ; numeric w, h ; +% wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; +% p +% if (w > 0) and (h > 0) : +% if xpart wh > 0 : xscaled (xpart wh/w) fi +% if ypart wh > 0 : yscaled (ypart wh/h) fi +% fi +% endgroup +% enddef ; +primarydef p xysized s = % a one step transform might be faster begingroup - save wh, w, h ; pair wh ; numeric w, h ; - wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; + save wh, w, h, b ; pair wh ; path b; + b := corners p ; + w := xpart point 1 of b - xpart point 0 of b ; + h := ypart point 2 of b - ypart point 1 of b ; + wh := paired (s) ; p - if (w>0) and (h>0) : + if (w > 0) and (h > 0) : if xpart wh > 0 : xscaled (xpart wh/w) fi if ypart wh > 0 : yscaled (ypart wh/h) fi fi endgroup enddef ; +% to be tested +% +% primarydef p xysized s = +% begingroup +% save wh, w, h ; pair wh ; numeric w, h ; +% wh := paired (s) ; w := bbwidth(p) ; h := bbheight(p) ; +% if (w > 0) and (h > 0) : +% transform t ; t := identity if xpart wh > 0 : xscaled (xpart wh/w) fi if ypart wh > 0 : yscaled (ypart wh/h) +% fi ; +% p if (w > 0) and (h > 0) : transformed t fi +% endgroup +% enddef ; + let sized = xysized ; permanent xsized, ysized, xysized, sized ; +% primarydef p xynormalized s = +% begingroup +% save w, h ; numeric w, h ; +% w := bbwidth(p) ; +% h := bbheight(p) ; +% if (w > 0) and (h > 0) : +% save t, wh ; transform t ; pair wh ; +% wh := paired (s) ; +% t := identity +% shifted - llcorner p +% if xpart wh > 0 : xscaled (xpart wh/w) fi +% if ypart wh > 0 : yscaled (ypart wh/h) fi +% ; +% p transformed t +% else : +% p +% fi +% endgroup +% enddef ; +primarydef p xynormalized s = + begingroup save w, h, b ; path b; + b := corners p ; + w := xpart point 1 of b - xpart point 0 of b ; + h := ypart point 2 of b - ypart point 1 of b ; + if (w > 0) and (h > 0) : + save t, wh ; transform t ; pair wh ; + wh := paired (s) ; + t := identity + shifted - llcorner p + if xpart wh > 0 : xscaled (xpart wh/w) fi + if ypart wh > 0 : yscaled (ypart wh/h) fi + ; + p transformed t + else : + p + fi + endgroup +enddef ; + +% primarydef p xnormalized s = +% begingroup +% save w ; numeric w ; +% w := bbwidth(p) ; +% if (w > 0) : +% save t ; transform t ; +% t := identity +% shifted - llcorner p +% if s > 0 : xscaled (s/w) fi +% ; +% p transformed t +% else : +% p +% fi +% endgroup +% enddef ; +primarydef p xnormalized s = + begingroup save h, r ; pair r ; + r := xrange p ; + w := ypart r - xpart r ; + if (w > 0) : + save t ; transform t ; + t := identity + shifted - llcorner p + if s > 0 : xscaled (s/w) fi + ; + p transformed t + else : + p + fi + endgroup +enddef ; + +% primarydef p ynormalized s = +% begingroup +% save h ; numeric h ; +% h := bbheight(p) ; +% if (h > 0) : +% save t ; transform t ; +% t := identity +% shifted - llcorner p +% if s > 0 : yscaled (s/h) fi +% ; +% p transformed t +% else : +% p +% fi +% endgroup +% enddef ; +primarydef p ynormalized s = + begingroup save h, r ; pair r ; + r := yrange p ; + h := ypart r - xpart r ; + if (h > 0) : + save t ; transform t ; + t := identity + shifted - llcorner p + if s > 0 : yscaled (s/h) fi + ; + p transformed t + else : + p + fi + endgroup +enddef ; + +permanent xnormalized, ynormalized, xynormalized ; + % def xscale_currentpicture(expr w) = % obsolete % currentpicture := currentpicture xsized w ; % enddef; @@ -775,10 +969,10 @@ lrcircle := origin -- (0,-.5) & (0,-.5){right} .. (+.5,0) & (+.5,0) -- cycle ; path tcircle, bcircle, lcircle, rcircle ; -tcircle = origin -- (+.5,0) & (+.5,0) {up} .. (0,+.5) .. {down} (-.5,0) -- cycle ; -bcircle = origin -- (-.5,0) & (-.5,0) {down} .. (0,-.5) .. {up} (+.5,0) -- cycle ; -lcircle = origin -- (0,+.5) & (0,+.5) {left} .. (-.5,0) .. {right} (0,-.5) -- cycle ; -rcircle = origin -- (0,-.5) & (0,-.5) {right} .. (+.5,0) .. {left} (0,+.5) -- cycle ; +tcircle := origin -- (+.5,0) & (+.5,0) {up} .. (0,+.5) .. {down} (-.5,0) -- cycle ; +bcircle := origin -- (-.5,0) & (-.5,0) {down} .. (0,-.5) .. {up} (+.5,0) -- cycle ; +lcircle := origin -- (0,+.5) & (0,+.5) {left} .. (-.5,0) .. {right} (0,-.5) -- cycle ; +rcircle := origin -- (0,-.5) & (0,-.5) {right} .. (+.5,0) .. {left} (0,+.5) -- cycle ; path urtriangle, ultriangle, lltriangle, lrtriangle ; % watch out: it's contrary to what you expect and starts in the origin @@ -801,13 +995,18 @@ path unitdiamond, fulldiamond ; unitdiamond := (.5,0) -- (1,.5) -- (.5,1) -- (0,.5) -- cycle ; fulldiamond := unitdiamond shifted - center unitdiamond ; +path unithexagon, fullhexagon ; + +unithexagon := for i within (unitcircle rotated 45/2) : pathpoint -- endfor cycle ; +fullhexagon := unithexagon shifted - center unithexagon ; + permanent fullsquare, unitcircle, urcircle, ulcircle, llcircle, lrcircle, tcircle, bcircle, lcircle, rcircle, urtriangle, ultriangle, lltriangle, lrtriangle, triangle, uptriangle, downtriangle, lefttriangle, righttriangle, - unitdiamond, fulldiamond ; + unitdiamond, fulldiamond, unithexagon, fullhexagon ; %D More robust: @@ -870,12 +1069,11 @@ enddef ; %D usage: \type{innerpath peepholed outerpath}. %D -%D beginfig(1); -%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; +%D \startMPcode %D fill (fullsquare scaled 200) withcolor red ; %D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; %D fill p peepholed bbox p ; -%D endfig; +%D \stopMPcode secondarydef p peepholed q = begingroup @@ -1118,11 +1316,24 @@ primarydef p crossed d = ( fi ) enddef ; +% vardef laddered primary p = % was expr +% point 0 of p +% for i=1 upto length(p) : +% -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) +% endfor +% enddef ; + vardef laddered primary p = % was expr - point 0 of p - for i=1 upto length(p) : - -- (xpart (point i of p), ypart (point (i-1) of p)) -- (point i of p) + save a; pair a ; a := point 0 of p ; a -- + for i within p : + if i > 0 : (xpart pathpoint, ypart a) -- pathpoint -- fi + hide(a := pathpoint) endfor + if cycle p : + (xpart point 0 of p, ypart a) -- point 0 of p -- cycle + else : + nocycle + fi enddef ; permanent crossed, laddered ; @@ -1168,18 +1379,55 @@ primarydef p randomshifted s = endgroup enddef ; +% vardef mfun_randomized_path(expr p,s) = +% for i=0 upto length(p)-1 : +% (point i of p) .. controls +% ((postcontrol i of p) randomshifted s) and +% ((precontrol (i+1) of p) randomshifted s) .. +% endfor +% if cycle p : +% cycle +% else : +% (point length(p) of p) +% fi +% enddef; +% +% Here is a Mikael Sundqvist improved version. This time we also use +% some new functionality. + vardef mfun_randomized_path(expr p,s) = - for i=0 upto length(p)-1 : - (point i of p) .. controls - ((postcontrol i of p) randomshifted s) and - ((precontrol (i+1) of p) randomshifted s) .. - endfor - if cycle p : - cycle - else : - (point length(p) of p) - fi -enddef; + save r, oldr, newr, firstr, l ; pair r, oldr, newr, firstr ; + r := paired(s) ; + l := length(p) ; + newr := (-1/2+uniformdeviate(1),-1/2+uniformdeviate(1)) xyscaled r ; + firstr := newr ; + for i within p : + hide ( + oldr := newr ; + newr := (-1/2+uniformdeviate(1),-1/2+uniformdeviate(1)) xyscaled r ; + ) + pathpoint .. + controls (pathpostcontrol shifted oldr ) + and ((deltaprecontrol 1) shifted if (i <> l - 1) : - newr else : - firstr fi) .. + endfor if cycle p : cycle else : nocycle fi +enddef ; + + +vardef mfun_randomrotated_path(expr p, s) = + save r, oldr, newr, firstr, l ; + l := length(p) ; + newr := (-1/2+uniformdeviate(1))*s ; + firstr := newr ; + for i within p : + hide ( + oldr := newr ; + newr := (-1/2+uniformdeviate(1)) * s ; + ) + pathpoint .. + controls (pathpostcontrol rotatedaround(pathpoint, oldr) ) + and ((deltaprecontrol 1) rotatedaround(deltapoint 1, if (i <> l - 1) : newr else : firstr fi)) .. + endfor if cycle p : cycle else : nocycle fi +enddef ; vardef mfun_randomized_picture(expr p,s)(text rnd) = save currentpicture ; @@ -1218,6 +1466,16 @@ primarydef p randomizedcontrols s = ( fi ) enddef ; +primarydef p randomrotatedcontrols s = ( + if path p : + mfun_randomrotated_path(p,s) + elseif picture p : + mfun_randomized_picture(p,s)(randomrotatedcontrols) + else : + p randomized s + fi +) enddef ; + primarydef p randomized s = ( if path p : for i=0 upto length(p)-1 : @@ -1271,7 +1529,8 @@ primarydef p randomized s = ( fi ) enddef ; -permanent superellipsed, squeezed, randomshifted, randomized, randomizedcontrols ; +permanent superellipsed, squeezed, randomshifted, randomized, + randomizedcontrols, randomrotatedcontrols ; %D Not perfect (alternative for interpath) @@ -1520,22 +1779,33 @@ def drawcontrollines expr c = path temp_c ; temp_c := c ; mfun_draw_controlline def drawpointlabels expr c = path temp_c ; temp_c := c ; mfun_draw_pointlabels enddef ; def mfun_draw_points text t = - for i=0 upto length(temp_c) if cycle temp_c : -1 fi : - normaldraw point i of temp_c mfun_opt_pnt t ; +% for i=0 upto length(temp_c) if cycle temp_c : -1 fi : +% normaldraw point i of temp_c mfun_opt_pnt t ; +% endfor ; + for i within temp_c : + normaldraw pathpoint mfun_opt_pnt t ; endfor ; enddef; def mfun_draw_controlpoints text t = - for i=0 upto length(temp_c) : - normaldraw precontrol i of temp_c mfun_opt_ctr t ; - normaldraw postcontrol i of temp_c mfun_opt_ctr t ; +% for i=0 upto length(temp_c) : +% normaldraw precontrol i of temp_c mfun_opt_ctr t ; +% normaldraw postcontrol i of temp_c mfun_opt_ctr t ; +% endfor ; + for i within temp_c : + normaldraw pathprecontrol t mfun_opt_pnt t ; + normaldraw pathpostcontrol t mfun_opt_pnt t ; endfor ; enddef; def mfun_draw_controllines text t = - for i=0 upto length(temp_c) : - normaldraw point i of temp_c -- precontrol i of temp_c mfun_opt_lin t ; - normaldraw point i of temp_c -- postcontrol i of temp_c mfun_opt_lin t ; +% for i=0 upto length(temp_c) : +% normaldraw point i of temp_c -- precontrol i of temp_c mfun_opt_lin t ; +% normaldraw point i of temp_c -- postcontrol i of temp_c mfun_opt_lin t ; +% endfor ; + for i within temp_c : + normaldraw pathpoint -- pathprecontrol t mfun_opt_pnt t ; + normaldraw pathpoint -- pathpostcontrol t mfun_opt_pnt t ; endfor ; enddef; @@ -1544,6 +1814,7 @@ numeric pointlabelscale ; pointlabelscale := 0 ; string pointlabelfont ; pointlabelfont := "" ; def mfun_draw_pointlabels text asked_options = + % todo: for i within temp_c : pathdirection for i=0 upto length(temp_c) if cycle temp_c : -1 fi : pair temp_u ; temp_u := unitvector(direction i of temp_c) rotated if swappointlabels : - fi 90 ; pair temp_p ; temp_p := (point i of temp_c) ; @@ -2631,12 +2902,31 @@ permanent smoothed, cornered, smoothcornered ; % 0 % fi % enddef ; - +% vardef bbwidth primary p = +% if unknown p : +% 0 +% elseif path p or picture p : +% xpart (lrcorner p - llcorner p) +% else : +% 0 +% fi +% enddef ; +% vardef bbwidth primary p = +% if unknown p : +% 0 +% elseif path p or picture p : +% save b ; path b; b := corners p ; +% xpart point 0 of b - xpart point 1 of b +% else : +% 0 +% fi +% enddef ; vardef bbwidth primary p = if unknown p : 0 elseif path p or picture p : - xpart (lrcorner p - llcorner p) + save r ; pair r ; r := xrange p ; + ypart r - xpart r else : 0 fi @@ -2653,12 +2943,31 @@ enddef ; % 0 % fi % enddef ; - +% vardef bbheight primary p = +% if unknown p : +% 0 +% elseif path p or picture p : +% ypart (urcorner p - lrcorner p) +% else : +% 0 +% fi +% enddef ; +% vardef bbheight primary p = +% if unknown p : +% 0 +% elseif path p or picture p : +% save b ; path b; b := corners p ; +% ypart point 2 of b - ypart point 1 of b +% else : +% 0 +% fi +% enddef ; vardef bbheight primary p = if unknown p : 0 elseif path p or picture p : - ypart (urcorner p - lrcorner p) + save r ; pair r ; r := yrange p ; + ypart r - xpart r else : 0 fi @@ -2817,15 +3126,19 @@ permanent withgray ; % an improved plain mp macro -vardef center primary p = - if pair p : - p - else : - .5[llcorner p, urcorner p] - fi -enddef; +% vardef center primary p = +% if pair p : +% p +% else : +% .5[llcorner p, urcorner p] +% fi +% enddef; +% +% permanent center ; -permanent center ; +vardef center primary p = + centerof p +enddef ; % new, yet undocumented @@ -3041,12 +3354,26 @@ permanent break ; %D New too: +% primarydef p xstretched w = ( +% p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi +% ) enddef ; primarydef p xstretched w = ( - p if (bbwidth (p)>0) and (w>0) : xscaled (w/bbwidth (p)) fi + begingroup save l, r ; pair r; + r := xrange p ; + l := ypart r - xpart r ; + p if (l > 0) and (w > 0) : xscaled (w/l (p)) fi + endgroup ) enddef ; +% primarydef p ystretched h = ( +% p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi +% ) enddef ; primarydef p ystretched h = ( - p if (bbheight(p)>0) and (h>0) : yscaled (h/bbheight(p)) fi + begingroup save l, r ; pair r; + r := yrange p ; + l := ypart r - xpart r ; + p if (l > 0) and (h > 0) : yscaled (h/l (p)) fi + endgroup ) enddef ; permanent xstretched, ystretched ; @@ -4061,3 +4388,31 @@ tertiarydef p cutafterlast q = mfun_p endgroup ; enddef ; + +% I don't want to define this path every time I make a demo: + +vardef starring(expr e) = + save a, b, c, d ; + pair a, b, c, d ; + a := (-1,-1) ; b := ( 1,-1) ; + c := ( 1, 1) ; d := (-1, 1) ; + a -- (.5[a,b] shifted (0,-e)) -- + b -- (.5[b,c] shifted (e, 0)) -- + c -- (.5[c,d] shifted (0, e)) -- + d -- (.5[d,a] shifted (-e,0)) -- cycle +enddef ; + +vardef dashing (expr pth, shp, stp) = + for i within arcpointlist stp of pth : + shp + rotated angle(pathdirection) + shifted pathpoint + && + endfor nocycle +enddef ; + +% like center, mod and div this is a candidate for a primitive + +% vardef centerofmass primary p = +% (origin for i within p : + pathpoint endfor) / length(p) +% enddef ; |