Article View: comp.lang.postscript
Article #8116Re: Bezier trees
From: Malcolm Sanders
Date: Fri, 17 Mar 1989 19:10
Date: Fri, 17 Mar 1989 19:10
188 lines
6910 bytes
6910 bytes
Rob Henley posted a PostScript code which drew fractal trees from
Bezier curves. By way of introduction he wrote--
>I've been reading this group with interest for a few weeks now and I thought
>some of you might be interested in a little program to draw trees - I start
>with a "curveto" curve and then recurse at a number of points on the curve.
>WARNING - don't try this unless your printer is otherwise unoccupied for a
>half hour or so!! I've also written a similar program in C to generate "flat"
>Postscript output. This allows me to "solve" the curve on the fly and tamper
>with each "branch" to my heart's content - I found the prospect of solving
>cubic equations in postfix rather daunting! If you've got any suggestions
>for improvements (this is my first Postscript program) ....
>version please let me know.....
Ah yes, where oh where does the path go? In your program, you generate
Bezier curves by issuing-
x0 y0 moveto x1 y1 x2 y2 x3 y3 curveto
where x0 and y0 are both given values of zero by virtue of a translate
command. The problem is to know if the point that you translate to
is on the curve or not.
Here is an attempt at a solution:
The Red Book notes that each Bezier curve is parameterized by a parameter
t ( in the interval [0,1]) in the following fashion.
x(t) = Ax*t^3 + Bx*t^2 + Cx*t + x0
y(t) = Ay*t^3 + By*t^2 + Cy*t + y0
where
x1 = x0 + Cx/3 y1 = y0 + Cy/3
x2 = x1 + (Cx + Bx)/3 y2 = y1 + (Cy + By)/3
x3 = x0 + Ax + Bx + Cx y3 = y0 + Ay + By + Cy
and by inversion of these linear relations, one obtains explicit
expressions for the coefficients in the parametric polynomials in
terms of the Bezier points, i.e.,
Ax = x3 - 3*x2 + 3*x1 - x0 Ay = y3 - 3*y2 + 3*y1 - y0
Bx = 3*(x2 - 2*x1 + x0) By = 3*(y2 - 2*y1 + y0)
Cx = 3*(x1 -x0) Cy = 3*(y1 - y0)
Thus, the choice of a Bezier curve by picking x0,x1,x2,x3,y0,y1,y2,y3
determines the values Ax, Bx, Cx, Ay, By, Cy. Points on the curve
are found by evaluating x(t),y(t) for various values of t. Note
that the position on the curve is a monotonically increasing function
of t as t goes from 0 to 1, although the relationship between t and
actual arclength along the curve is not simple(it involves the
evaluation of a particularly nasty integral.)
I incorporated these ideas into Rob's code and I am posting the
result. You can play with different Bezier points and the code
will insure that all the recursions begin on the curves that were
drawn during the previous recursion level(PRL). Playing with the
parameter t will put branches in different places.
I also monkeyed around with the angles so that the angle variable
which tree eats will be the angle between the tree and the branch
(branch and twig,...) rather than an absolute angle in the PRL
graphics state.
Anyway here follows another stage in the evolution of PostScript
fractal trees.
------------------------------- Cut Here --------------------------------------
%! ------- Bezier Trees --------
% Code by Rob Henley at Siemens SDG
% Mutation by Malcolm Sanders at Yale
%
% --------- Variables and Procedures -------------
% define the Bezier points...
/x0 0 def
/y0 0 def
/x1 -200 def
/y1 100 def
/x2 300 def
/y2 400 def
/x3 -200 def
/y3 600 def
% ...then use them to determine the polynomial coefficients
/Ax x3 x2 x1 sub 3 mul sub x0 sub def
/Ay y3 y2 y1 sub 3 mul sub y0 sub def
/Bx x2 x1 2 mul sub x0 add 3 mul def
/By y2 y1 2 mul sub y0 add 3 mul def
/Cx x1 x0 sub 3 mul def
/Cy y1 y0 sub 3 mul def
% Procedures to evaluate coordinates on Bezier curve-- t on top of stack
/xt {dup dup Ax mul Bx add mul Cx add mul x0 add} def
/yt {dup dup Ay mul By add mul Cy add mul y0 add} def
% Procedures for setting branching angles
/dxt {dup Ax 3 mul mul Bx 2 mul add mul Cx add} def
/dyt {dup Ay 3 mul mul By 2 mul add mul Cy add} def
/baseangle Cy Cx atan def
/curveangle {dup dyt exch dxt atan} def
/depth 0 def
/maxdepth 5 def
/down {/depth depth 1 add def} def
/up {/depth depth 1 sub def} def
/tree
{
gsave
dup dup xt exch yt
translate % new user space
curveangle baseangle sub exch add
rotate % rotate
.3 .3 scale % reduce scale
0 0 moveto % move to origin
6 copy % copy 6 top items
curveto % Bezier cubic
stroke % mark the path
% -- recurse at points calculated to be on the curve --
% -- with specified branching angles --
down
depth maxdepth le
{
140 .5 tree
-30 .625 tree
120 .69 tree
-40 .8 tree
100 .9 tree
-60 .95 tree
60 1 tree
-30 1 tree
} if
up
grestore
} def
/season
{
gsave
translate
/maxdepth exch def
200 100 translate
x1 y1 x2 y2 x3 y3 0 0 tree
grestore
} def
/printbanner
{180 20 moveto (Winter Spring Summer) show} def
% ------- Begin Program --------
newpath
/Times-Italic findfont 30 scalefont setfont
.95 -.05 0 {setgray printbanner -1 .5 translate} for
1 setgray
printbanner
0 setgray
0 0 moveto
2 0 350 season
3 300 350 season
4 0 0 season
5 300 0 season
showpage
------------------------------- Cut Here --------------------------------------
__________ ____ ____
____ ____ ____ __________
__________ |\ /| |\ /| / \ ____ ____
____ ____ | \ / | | \ / | \____ __________
__________ | \ / | | \ / | \ ____ ____
____ ____ | \/ |o | \/ |o \___ /o __________
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ Malcolm M. Sanders BITNET: sanders@yalevms @@@
@@@ Applied Physics ARPANET: sanders@venus.ycc.yale.edu @@@
@@@ Yale Station Box 2159 @@@
@@@ New Haven, CT 06520 bellnet: (203) 432-4324 @@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Technical Details
Message-ID:
<53977@yale-celray.yale.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!yale!sanders%yale-zoo-sunedReferences:
<1189@argon.siesoft>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!yale!sanders%yale-zoo-suned From: sanders%yale-zoo-suned@CS.YALE.EDU (Malcolm Sanders) Newsgroups: comp.lang.postscript Subject: Re: Bezier trees Message-ID: <53977@yale-celray.yale.UUCP> Date: 17 Mar 89 19:10:27 GMT References: <1189@argon.siesoft> Sender: root@yale.UUCP Reply-To: sanders%yale-zoo-suned@CS.YALE.EDU (Malcolm Sanders) Organization: Yale University Computer Science Dept, New Haven CT 06520-2158 Lines: 188