0

Currently I am drawing a 3D curve consisting of 1200...1500 straight micro-lines directed by an array of 3D points (x,y,z), but rendering is a bit slow regardless of used technology (Adobe Flash, Three.js).

The curve is a kind of 3D arc with a 180 degree loop at the end, so I thought that skipping some points in places where the curve is more smooth and predictable will speed up rendering.

Could you suggest some algorithm which can determine how close to a straight line the specific piece of 3D curve is?

Update

I tried to make Three.js to render these points as a single curve and it works really fast. But the different pieces of this curve should be differently colored, so I have to draw it as a bunch of separate lines and the only thing I can do to speed it up is to skip every second point in a region where line is close to a straight line.

I can not use OpenGL (WebGL) because not all browsers support it.

Paul
  • 25,812
  • 38
  • 124
  • 247
  • Could you draw it once to a texture and then just keep reusing that or does it change dynamically and constantly? – Michael Dorgan May 29 '13 at 16:17
  • @Michael Dorgan: The looped arc should be rotated, scaled and panned by the mouse and it does not fit on a plane. And yeah: the pieces of this line should go visible or invisible depending on trackbar's thumb position. – Paul May 29 '13 at 16:23
  • Well that's out then and I'm beyond my expertise to suggest much else. My first thought was a bunch of small line polys placed in a display list so that they didn't need to be recreated every tic, but I cannot say how to do that in flash. You should retag your question to Flash to get some more expert eyes on this. – Michael Dorgan May 29 '13 at 16:26
  • @Michael Dorgan: It is not about Flash. Currently I am planning to move off the Flash. It is a more general question but not about a specific technology. – Paul May 29 '13 at 16:28
  • With a little OpenGL, you could do what I suggest pretty quickly and portably. Again though, tagging this OpenGL will get you a nicer response as well. Writing 1500 polys in OpenGL will not be a performance hitch :) – Michael Dorgan May 29 '13 at 16:32
  • I would also suggest OpenGL, and I would have written that as an answer except you phrased the question to avoid technology answers... Something using cached derivatives would be how I would start to approach an algorithm for curve straightness though. – Ben May 29 '13 at 16:34
  • @Michael Dorgan: WebGL does not work in all browsers, so I abandoned it. The question was not about what technology I should use, but about an algorithm. Think of it as of mathematical 3D task. – Paul May 29 '13 at 16:35
  • Bezier curve? http://cs1.bradley.edu/public/jcm/cs535BezierCurve.html – 3Dave May 29 '13 at 16:38
  • Aw! I missed that from the question. Bezier curve is also my first thought. – Michael Dorgan May 29 '13 at 16:39
  • Bezier curve algorithm, as I understand, is used in drawing, but not in determining how close three points are to a straingt line. I need to skip points - that is the primary task. The question is - which ones I can skip easily? (The curve is gradiently colored, so I can't draw it as a single Bezier curve). – Paul May 29 '13 at 16:39
  • 1
    My 3d mathematics is not quite good enough to provide an actual -answer-, but here's a useful looking section on wikipedia containing an equation to calculate the curvature of 3d curves: http://en.wikipedia.org/wiki/Curvature#Curvature_of_space_curves - possibly the second on using an arc and chord would be useful to you, as you have a collection of such segments? – Ben May 29 '13 at 16:43
  • @Ben: `Curvature of space curves`! Thank you, now I know the right words. – Paul May 29 '13 at 16:50

1 Answers1

0

The difference between three points and a straight line can be quantified from the distance of the middle one from the line on which the other two rest. Probably getting the two lengths along the line from either end point to the middle one, dividing the distance by both and summing the two results is the easiest way to turn it into a single number.

So:

  • as the middle point gets closer to the line, the number goes down;
  • as the line segment grows longer, variations by the mid point need to be proportionally more extreme; and
  • greater local slope (as if the middle point were very close to either end) produces a greater error.

You can get the distance from a position to a line by obtaining the vector from any point on the line to the position, using the dot product to work out how much of that is movement along the line and then subtracting that from the total. If you don't normalise your vector along the line first you end up having multiplied by the square of it, so no need for a square root operation on that account. Then for the implied length calculation you can just keep and compare all of those as squared.

Tommy
  • 99,986
  • 12
  • 185
  • 204