3

I've been working on a problem for several weeks and have reached a point that I'd like to make sure I'm not overcomplicating my approach. This is being done in OpenGL ES 2.0 on iOS, but the principles are universal, so I don't mind the answers being purely mathematical in form. Here's the rundown.

I have 2 points in 3D space along with a control point that I am using to produce a bezier curve with the following equation:

B(t) = (1 - t)2P0 + 2(1 - t)tP1 + t2P2

The start/end points are being positioned at dynamic coordinates on a fairly large sphere, so x/y/z varies greatly, making a static solution not so practical. I'm currently rendering the points using GL_LINE_STRIP. The next step is to render the curve using GL_TRIANGLE_STRIP and control the width relative to height.

According to this quick discussion, a good way to solve my problem would be to find points that are parallel to the curve along both sides taking account the direction of it. I'd like to create 3 curves in total, pass in the indices to create a bezier curve of varying width, and then draw it.

There's also talk of interpolation and using a Loop-Blinn technique that seem to solve the specific problems of their respective questions. I believe that the solutions, however, might be too complex for what I'm going after. I'm also not interested bringing textures into the mix. I prefer that the triangles are just drawn using the colors I'll calculate later on in my shaders.

So, before I go into more reading on Trilinear Interpolation, Catmull-Rom splines, the Loop-Blinn paper, or explore sampling further, I'd like to make sure what direction is most likely to be the best bet. I think I can say the problem in its most basic form is to take a point in 3D space and find two parallel points along side it that take into account the direction the next point will be plotted.

Thank you for your time and if I can provide anything further, let me know and I'll do my best to add it.

Community
  • 1
  • 1
Javier Otero
  • 118
  • 2
  • 7
  • Do you need the width to be measured in 3 Dimensional space and independent of the view direction or do you want to have a static width "onscreen" (lets say the ends should always be 1 pixel and the middle 5 pixels wide)? – Nobody moving away from SE Jun 06 '12 at 17:23
  • The width will need to be considered in 3D space instead of pixels since it is being worked on within OpenGL. It should technically be independent of the view direction and will most likely be much less dynamic than the other bezier points to be calculated. – Javier Otero Jun 06 '12 at 17:39

1 Answers1

2

This answer does not (as far as I see) favor one of the methods you mentioned in your question, but is what I would do in this situation.

I would calculate the normalized normal (or binormal) of the curve. Let's say I take the normalized normal and have it as a function of t (N(t)). With this I would write a helper function to calculate the offset point P:

P(t, o) = B(t) + o * N(t)

Where o means the signed offset of the curve in normal direction.

Given this function one would simply calculate the points to the left and right of the curve by:

Points = [P(t, -w), P(t, w), P(t + s, -w), P(t + s, w)]

Where w is the width of the curve you want to achieve.

Then connect these points via two triangles.

For use in a triangle strip this would mean the indices:

0 1 2 3

Edit

To do some work with the curve one would generally calculate the Frenet frame.

This is a set of 3 vectors (Tangent, Normal, Binormal) that gives the orientation in a curve at a given parameter value (t).

The Frenet frame is given by:

unit tangent = B'(t) / || B'(t) ||
unit binormal = (B'(t) x B''(t)) / || B'(t) x B''(t) ||
unit normal = unit binormal x unit tangent

In this example x denotes the cross product of two vectors and || v || means the length (or norm) of the enclosed vector v.

As you can see you need the first (B'(t)) and the second (B''(t)) derivative of the curve.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • It's quite alright if the answer is a departure from the methods I mentioned, I like that :) The logic seems like a great way to go, for simplicity sake. I am still somewhat struggling with normalizing, however. In this case, I'm specifically not sure what the normal of the curve is referring to. I hate to ask you to elaborate a bit on that, but I think it will help me grasp it further. Really appreciate it! – Javier Otero Jun 06 '12 at 20:40
  • @JavierOtero added a paragraph about the normal. I hope it makes sense now. – Nobody moving away from SE Jun 07 '12 at 08:03
  • I'll keep you updated on how it goes, so far it's making sense :) – Javier Otero Jun 07 '12 at 15:30