Question

I have 2 points in X,Y + Rotation and I need to calculate a bezier spline (a collection of quadratic beziers) that connects these 2 points smoothly. (see pic) The point represents a unit in a game which can only rotate slowly. So to get from point A to B, it has to take a long path. The attached picture shows quite an exaggeratedly curvy path, but you get the idea.

alt text

What formulas can I use to calculate such a bezier spline?

Was it helpful?

Solution

Just saw that I misunderstood your question. Couldn't you use a single cubic hermite splines instead since you have a start and end point and two directions (tangents)? Are there any additional constraints?

To calculate the start and end tangents just use the start and end direction and scale them with the distance between the start and end points (and additionally some other constant factor like 0.5 depending on how curvy you want the path to be).:

p0 = startpoint;
p1 = endpoint;
float scale = distance(p0, p1);
m0 = Vec2(cos(startangle), sin(startangle)) * scale;
m1 = Vec2(cos(endangle), sin(endangle)) * scale;

I use this system to interpolate camera paths in a game I'm working on and it works great.

OTHER TIPS

As you probably know, there are infinite solutions, even if we assume 2 control points.

I found Smoothing Algorithm Using Bézier Curves, which answers your question (see equations of Bx(t) and By(t) in the beginning):

Bx(t) = (1-t)3 P1x + 3 (1-t)2 t  P2x + 3 (1-t) t2 P3x + t3 P4x

By(t) = (1-t)3 P1y + 3 (1-t)2 t  P2y + 3 (1-t) t2 P3y + t3 P4y

P1 and P4 are your endpoints, and P2 and P3 are the control points, which you're free to choose along the desired angles. If your control point is at a distance r along an angle θ from point (x, y), the coordinates of the point are:

x' = x - r sin(θ)

y' = y - r cos(θ)

(according to the co-ordinate system you've used—I think I got the signs right). The only free parameter is r, which you can choose as you want. You probably want to use

r = α dist(P1, P4)

with α < 1.

I don't remember where I got it, but I have been using this:

Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
      float u = 1 - t; 
      float tt = t*t;
      float uu = u*u;
      float uuu = uu * u;
      float ttt = tt * t;

      Vector2 p = uuu * p0; //first term
      p += 3 * uu * t * p1; //second term
      p += 3 * u * tt * p2; //third term
      p += ttt * p3; //fourth term

      return p;
}

where t is ratio along path between start and end points.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top