[comp.graphics] Shrinking Bezier curves

pm@allgfx.agi.oz (Peter Merrylees) (07/27/90)

I would like to shrink a cubic Bezier curve by a constant weight to produce
a new Bezier curve.  The perpendicular distance between the two curves must
be constant at all points on the curves.

Input:	4 control points
	weight

Output:	4 new control points

Note: This is not a linear transformation.

Can anyone assist please?

Peter Merrylees
All Graphic R&D
pm@allgfx.agi.oz.au

spencer@eecs.umich.edu (Spencer W. Thomas) (07/27/90)

Question: offsetting Bezier curves.

Simple answer: Can't be done.  The result is not a Bezier curve.

Simple demonstration: start with a parabola.  Pick a "large enough"
offset.  The resulting offset curve has a loop in it.  This is
certainly not a quadratic curve any longer (you can't put a loop in a
quadratic).  In fact, it's not a polynomial.

More justification: The offset is a normal vector to the curve, of
constant length.  To get the "constant length" part, you need to take
a square root:
	offset_vec = const * normal_vec / length(normal_vec)
where	normal_vec = d/dt ( curve )
and	length(vec) = sqrt(vec_x^2 + vec_y^2 + vec_z^2);

d/dt is a linear operator which, when applied to a polynomial (Bezier)
curve, results in a polynomial (Bezier) curve.  sqrt is a non-linear
operator, so the result is not polynomial (or Bezier), unless you are
really lucky.

A possible solution: subdivide the curve into lots of little
almost-straight pieces, then compute an approximate offset curve for
each.  This computation is not trivial if you want to maintain some
(i.e., tangent) continuity, but can be done.  I'll sketch a possible
solution (maybe someone else out there can come up with a better one).
For now, assume the curve is cubic (so there are four control points);
the solution is more complex (i.e., more than I want to think about
right now) for higher degrees.
	For each Bezier (defined by p0, p1, p2, p3):
		Offset the endpoints according to the above equation,
			resulting in p0', p3'.
		d = distance( p0, p3 );
		d' = distance( p0', p3' );
		tan0 = p1 - p0;
		tan1 = p2 - p3;
		p1' = p0' + (d'/d) * tan0;
		p2' = p3' + (d'/d) * tan1;

This preserves tangent continuity, but fails in the case where the
initial offset operation reverses p0 and p3 (i.e., where a loop would
be introduced).  It can be fixed, but I'll leave that as "an exercise
for the reader".

=Spencer W. Thomas 		EECS Dept, U of Michigan, Ann Arbor, MI 48109
spencer@eecs.umich.edu		313-936-2616 (8-6 E[SD]T M-F)

--
=Spencer W. Thomas 		EECS Dept, U of Michigan, Ann Arbor, MI 48109
spencer@eecs.umich.edu		313-936-2616 (8-6 E[SD]T M-F)

tima@agora.uucp (Tim Anderson) (07/27/90)

By now you probably know that you can't do this, but you can get 'close'...

Another approach is to do what the IGES spec. does, leave the original 
curve - but put in an 'offset' value. So when you go to re-create these
curves, you calculate the point and tangent vector then offset the 
appropriate distance. This approach leads to a 'true' offset (or as true
as you can get!) with the benefit of not having to drain your brain to
figure out a way to calculate a real approximation. This is the approach
that I am taking to offset NURBS in our CAM system, simply because
generating approximate offset NURBS is a nightmare AND I have to get this
done before September...

see ya' at IMTS!

tima@agora.hf.intel.com
tektronix!tessi!agora!tima

PS Don't forget that offset curves have a nasty habit of backing up on 
   themselves. This is called 'gouging' in the CAM business. Let's just
   hope that no one wants to make anything that has too sharp a curve in
   it! ;-)