4

I'm trying to render a "3D ribbon" using a single 3D cubic Bézier curve to describe it (the width of the ribbon is some constant). The first and last control points have a normal vector associated with them (which are always perpendicular to the tangents at those points, and describe the surface normal of the ribbon at those points), and I'm trying to smoothly interpolate the normal vector over the course of the curve.

For example, given a curve which forms the letter 'C', with the first and last control points both having surface normals pointing upwards, the ribbon should start flat, parallel to the ground, slowly turn, and then end flat again, facing the same way as the first control point. To do this "smoothly", it would have to face outwards half-way through the curve. At the moment (for this case), I've only been able to get all the surfaces facing upwards (and not outwards in the middle), which creates an ugly transition in the middle.

It's quite hard to explain, I've attached some images below of this example with what it currently looks like (all surfaces facing upwards, sharp flip in the middle) and what it should look like (smooth transition, surfaces slowly rotate round). Silver faces represent the front, black faces the back.

Incorrect, what it currently looks like:

Correct Ribbon http://img211.imageshack.us/img211/4659/ribbonincorrect.th.png

Correct, what it should look like:

Incorrect Ribbon http://img515.imageshack.us/img515/2673/ribboncorrect.th.png

All I really need is to be able to calculate this "hybrid normal vector" for any point on the 3D cubic bézier curve, and I can generate the polygons no problem, but I can't work out how to get them to smoothly rotate round as depicted. Completely stuck as to how to proceed!

Robert
  • 5,735
  • 3
  • 40
  • 53

1 Answers1

2

You may use the algorithm explained in the first part of this answer, evaluating the normals at t=0 (or a fixed t, whichever you choose) will give you a smooth transition.

Like this:

alt text

(Imagine your sidewalk along the blue-red border)

Edit

Ok, this is what I got by another way:

alt text

The procedure is simple:

Have your parametrized function:

f[t] := { x[t], y[t], z[t] }  

Calculate the tangent vector by taking derivatives:

f'[t] := { x'[t], y'[t], z'[t] }  

Chose your starting (and ending normal vector) for example:

n[0] = {0, 0, 1};

Now define another function as the vector product of the derivative and your normal:

cp[t_] := CrossProduct[f'[t], n[0]];  

And that's it.

The points of my quadrilaterals lie in:

 {f[t] - cp[t]/3, 
  f[t] + cp[t]/3, 
  f[t + dt] + cp[t + dt]/3, 
  f[t + dt] - cp[t + dt]/3}  

where dt is the increment you like.

A more sophisticated approach may account for the curve path length, but I guess that is the second iteration of the algorithm.

HTH!

Community
  • 1
  • 1
Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • The image appears to depict what I'm after, but I'm having trouble making sense of the equations used. Specifically, I'm mostly only familiar with C-like languages... I don't suppose you could explain the equations a little more? – Robert Dec 27 '10 at 00:02
  • @Robert No problem, but I don't want to write a book. Those are math functions. If you let me know where your trouble is, I could try to help! – Dr. belisarius Dec 27 '10 at 00:09
  • Okay, I sort of get your math functions—I was getting confused on your circle equation. Then am I right in thinking that the mentioned orthogonal plane is more or less what I need to calculate? Is the surface normal of that plane (at some position t) the same vector I'm trying to calculate? I have the parametric equations of my Bézier to hand and have calculated their derivatives for finding the tangent, so perhaps tomorrow when I'm not tired I'll have a go at putting them into practice. In the meantime, thanks for your help! – Robert Dec 27 '10 at 00:21
  • @Robert All you wrote is right. It seems you are right on your path. Just be aware that the circles are giving you really TWO equations (with +/- Sqrt[]) the blue/red line is between those solutions, which you better get as parametric so you can fix the angle through your path. – Dr. belisarius Dec 27 '10 at 00:27
  • @belisarius Thanks for all the help so far, but I'm still getting confused... I've been going through the equations, but how do I calculate the circle equation? (Using some graphing software, I can't get anything but spheres which happen to be bisected the plane.) After I have the equation of the circle, how do I then calculate the normal I'm after? – Robert Dec 27 '10 at 15:13
  • @Robert I was working a bit with this one, and although I can get a slow transition the effect is not exactly what you want. If I find a good way to achieve exactly what you want I'll come back with more. – Dr. belisarius Dec 27 '10 at 22:18
  • @belisarius Thanks, incidentally, the effect I'm trying to achieve is implemented _exactly_ in a roller coaster simulator called NoLimits - http://www.nolimitscoaster.com/index.html - if you're interested, the editor in the demo seems to calculate in real time the normals of a section of track (a cubic Bézier) in a manor that I'm after. – Robert Dec 28 '10 at 00:03
  • @Robert Already did the calculations. Posting in a few minutes. I'm producing the graphics – Dr. belisarius Dec 28 '10 at 00:09
  • @belisarius Thanks, I've looked over the equations and, as far as I can tell, I _think_ it's already the way I calculate it, and that it would still suffer from the "overlap" for certain curves (such as the 'C'-type curve in the original question). If, for example, the parametric functions in your example were x[t] := Sin[t], y[t] := 0 and z[t] := t for t := 0..π (just so it create's a sort of flat 'C'), and the normals at the beginning and end were both {0, 0, 1}, wouldn't your graph look like the "incorrect ribbon" picture? (Or would it turn round to one side as it should?) – Robert Dec 28 '10 at 18:41
  • @Robert The problem is that your curve "lives" in 2D, so the y component is never generated. Let me think a little about it to see if I can fake an y component. – Dr. belisarius Dec 28 '10 at 19:12
  • It's a space curve; I'd have just used the usual expressions for the normal and binormal vectors (whichever of the two is appropriate). –  Dec 30 '10 at 06:43
  • reviving a bit of an old post, but if you want "The true normals at the start and end point" rather than arbitrarily picking some values, Bezier curves are the `[0,1]` interval of a parametric polynomial, so you can find the tangential plane at t=0 and t=1 by looking at the second derivative of the curve at those points, which tells us the "rate of change, of the rate of change", giving us the plane that the tangent vector lies on, and thus the plane through which we need to rotate to get the normal vector. – Mike 'Pomax' Kamermans Apr 07 '17 at 15:13