Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing part of a Bézier curve by reusing a basic Bézier-curve-function?

Assuming I'm using some graphic API which allows me to draw bezier curves by specifying the 4 necessary points: start, end, two control points.

Can I reuse this function to draw x percent of the 'original' curve (by adjusting the control points and the end point)?

Or is it impossible?

Unnecessary information, should someone care:

  • I need the whole thing to draw every n % of the original
    bezier curve with different color and/or line style
  • I'm using Java's Path2D to draw bezier curves:

    Path2D p = new GeneralPath();
    p.moveTo(x1, y1);
    p.curveTo(bx1, by1, bx2, by2, x2, y2);
    g2.draw(p);
    
like image 460
ivan_ivanovich_ivanoff Avatar asked May 18 '09 17:05

ivan_ivanovich_ivanoff


People also ask

How do you draw a Bezier curve?

To draw a line using this equation, one can divide the curve into smaller segments, calculate the end points of each segment using the Bezier cubic equation and draw the line for the segment. For instance, one can draw a line between the points defined by t = 0 and t = 0.01, then t = 0.01 and t = 0.02, and so on.

What is the function of Bezier curve?

Bézier curves are widely used in computer graphics to model smooth curves. As the curve is completely contained in the convex hull of its control points, the points can be graphically displayed and used to manipulate the curve intuitively.

What will happen if the position of a control point of an already drawn Bezier curve is changed?

Changing the position of a control point will change the shape of the defined Bézier curve.

How do you find the equation of a Bezier curve?

Number of points i.e. k=4, Hence, we know that the degree of the Bezier curve is n= k-1= 4-1= 3. Hence, P0(2,2,0) and B0,3=(1−u)3,P1(2,3,0) and B1,3=3u(1−u)2,P2(3,3,0) and B2,3=3u2(1−u) andP2(3,2,0) and B3,3=u3.


2 Answers

What you need is the De Casteljau algorithm. This will allow you to split your curve into whatever segments you'd like.

However, since you're dealing with just cubic curves, I'd like to suggest a slightly easier to use formulation that'll give you a segment from t0 to t1 where 0 <= t0 <= t1 <= 1. Here's some pseudocode:

u0 = 1.0 - t0
u1 = 1.0 - t1

qxa =  x1*u0*u0 + bx1*2*t0*u0 + bx2*t0*t0
qxb =  x1*u1*u1 + bx1*2*t1*u1 + bx2*t1*t1
qxc = bx1*u0*u0 + bx2*2*t0*u0 +  x2*t0*t0
qxd = bx1*u1*u1 + bx2*2*t1*u1 +  x2*t1*t1

qya =  y1*u0*u0 + by1*2*t0*u0 + by2*t0*t0
qyb =  y1*u1*u1 + by1*2*t1*u1 + by2*t1*t1
qyc = by1*u0*u0 + by2*2*t0*u0 +  y2*t0*t0
qyd = by1*u1*u1 + by2*2*t1*u1 +  y2*t1*t1

xa = qxa*u0 + qxc*t0
xb = qxa*u1 + qxc*t1
xc = qxb*u0 + qxd*t0
xd = qxb*u1 + qxd*t1

ya = qya*u0 + qyc*t0
yb = qya*u1 + qyc*t1
yc = qyb*u0 + qyd*t0
yd = qyb*u1 + qyd*t1

Then just draw the Bézier curve formed by (xa,ya), (xb,yb), (xc,yc) and (xd,yd).

Note that t0 and t1 are not exactly percentages of the curve distance but rather the curves parameter space. If you absolutely must have distance then things are much more difficult. Try this out and see if it does what you need.

Edit: It's worth noting that these equations simplify quite a bit if either t0 or t1 is 0 or 1 (i.e. you only want to trim from one side).

Also, the relationship 0 <= t0 <= t1 <= 1 isn't a strict requirement. For example t0 = 1 and t1 = 0 can be used to "flip" the curve backwards, or t0 = 0 and t1 = 1.5 could be used to extend the curve past the original end. However, the curve might look different than you expect if you try to extend it past the [0,1] range.

Edit2: More than 3 years after my original answer, MvG pointed out an error in my equations. I forgot the last step (an extra linear interpolation to get the final control points). The equations above have been corrected.

like image 187
Naaff Avatar answered Sep 24 '22 02:09

Naaff


In an answer to another question I just included some formulas to compute control points for a section of a cubic curve. With u = 1 − t, a cubic bezier curve is described as

B(t) = u3P1 + 3u2t P2 + 3ut2P3 + t3P4

P1 is the start point of the curve, P4 its end point. P2 and P3 are the control points.

Given two parameters t0 and t1 (and with u0 = (1 − t0), u1 = (1 − t1)), the part of the curve in the interval [t0, t1] is described by the new control points

  • Q1 = u0u0u0P1 + (t0u0u0 + u0t0u0 + u0u0t0) P2 + (t0t0u0 + u0t0t0 + t0u0t0) P3 + t0t0t0P4
  • Q2 = u0u0u1P1 + (t0u0u1 + u0t0u1 + u0u0t1) P2 + (t0t0u1 + u0t0t1 + t0u0t1) P3 + t0t0t1P4
  • Q3 = u0u1u1P1 + (t0u1u1 + u0t1u1 + u0u1t1) P2 + (t0t1u1 + u0t1t1 + t0u1t1) P3 + t0t1t1P4
  • Q4 = u1u1u1P1 + (t1u1u1 + u1t1u1 + u1u1t1) P2 + (t1t1u1 + u1t1t1 + t1u1t1) P3 + t1t1t1P4

Note that in the parenthesized expressions, at least some of the terms are equal and can be combined. I did not do so as the formula as stated here will make the pattern clearer, I believe. You can simply execute those computations independently for the x and y directions to compute your new control points.

Note that a given percentage of the parameter range for t in general will not correspond to that same percentage of the length. So you'll most likely have to integrate over the curve to turn path lengths back into parameters. Or you use some approximation.

like image 26
MvG Avatar answered Sep 24 '22 02:09

MvG