math & physics
xcrypt at November 2nd, 2011 16:21 — #1
I'm trying to create some kind of demo that rushes through a tunnel.
I have made a random path generator that creates smooth looking paths in 3D space (just some 3D points)
Now I would like to create polies that form a tunnel around that path.
To give an example, let us assume that the path only extends towards the Z axis.
(so path_pos.x and path_pos.y will remain 0)
then I could define the positions of the vertices as:
x = path_pos.x + cos(t)*radius;
y = path_pos.y + sin(t)*radius;
z = path_pos.z;
However, as mentioned before, I would like the polies to form a smooth tunnel around that path,
and the path rotates to the x and y axis as it progresses.
This means that we have to adjust the formula, else it would start looking deformed, and
the radius of the tunnel would be depending on the angles between the path points...
(See the given image, the small green circles represent the path points,
and the red lines represent circles on which I have to define the points of the polies)
(first image is the problem rendered with 3dsmax,
second and third are images made with paint to represent the problem more mathematically)
As we can see from the image, the x and y component from path_pos2
could actually be the same than the ones from path_pos1,
with a different Z component for every point in the circle.
I could define the following:
z = path_pos.z + ( ( cot( (anglebetween([p1,p2],[p2,p3])/2 ) * (radius*2) ) *
( (radius*2)/(radius+(y-p2.y)) ) );
But I think this is only the case because the line(path_pos1,path_pos2) is parallel to the Z axis.
When the path starts making 'rotations'/'turns', both around x(pitches) and y(yaws) axis,
I'm not sure how to define the points around the pathpoint that should form an ellipse,
so that the radius of the tunnel would remain the same (except in the actual corners, for efficiency).
I really hope this doesn't sound like a shitstorm, I tried my best to explain...
Could anyone please help?
reedbeta at November 2nd, 2011 18:03 — #2
I can't see your images; I get a 403-forbidden error. However, it sounds like what you'd want to do is basically sweep a circle along the path in short increments, rotating the circle to align with the tangent vector of the path at each stop, and construct cylinders of polygons between each circle and the next.
xcrypt at November 2nd, 2011 18:28 — #3
I updated the links, can you see them now?
Also, how could I find the tangent vector of the path at a given point (especially when the path can turn both left/right and up/down at the same time), and what is a good way to align the ellipse to it?
reedbeta at November 2nd, 2011 18:57 — #4
Ahh, yes I see them now. Is your path always in the form of line segments like that, or do you have a more smoothly curving path like a spline? If you have a smoothly curving path, then doing what I said should work but you'll have to take smaller step sizes to avoid too much distortion. You find the tangent vector by taking the derivative of the curve equation.
If you actually want to do sharp bends in a path that's otherwise straight, like you showed in your diagram, then I'd probably generate a sector of a torus to fill in the bend.
In either case, to align the circle or torus with the path, you could use a look-at matrix, passing the tangent vector in as the look-at vector.
xcrypt at November 2nd, 2011 19:46 — #5
I'm not working with splines (would be sort of inefficient I suppose), however I can supply my random path generator with parameters that could make it look smooth, so it wouldn't get that much deformation.
I'm not sure what you mean with generating a sector of a torus though?
Where I want to go with this, is more like the way that 3dsmax handles the problem.
Unfortunately it doesn't show me the formula they use
Edit: and thanks again! You just helped me a bunch
reedbeta at November 2nd, 2011 20:09 — #6
By a sector of a torus, I mean this (the blue-and-red part). You just generate the fraction of the torus needed for the angle change between the two segments of pipe.
xcrypt at November 2nd, 2011 20:34 — #7
I'll try out some more stuff tomorrow then, thanks for pointing me in the right direction
thenut at November 2nd, 2011 22:47 — #8
You should definitely look into Bezier paths for this sort of thing. Just plot your path and build your cylindrical mesh using the orthonormal basis you derive from the path. It's extremely flexible what you can do with it. If you have WebGL, check out this quick demo I made. Paths can be as efficient as you want it to be. You can have very high detail or virtually none. If you're only interested in smoothing the joints, you can easily construct your geometry such that one segment in the path uses X number of polygons while the bend segment uses Y number of polygons. The algorithm for calculating this curvature is exactly what Reedbeta said in his first post.
The best thing about Bezier paths is you can easily manipulate them. You can interpolate the radius along the path to produce interesting solids (like tree branches) and you easily move control points around to add different slopes, rotations, or to construct complex geometric shapes. The torus shape in my demo for example is nothing more than a looped path (6 control points in total).
If you have Blender 3D, you can see what 2D and 3D representations of Bezier paths look like, and even play around with it to get a good feeling of how it works.
xcrypt at November 3rd, 2011 08:08 — #9
Hmm, looks like I stumbled upon another problem... I got the tangent, but the MatrixLookAt needs an "up" vector, I suppose this is the normal? I know we can get the binormal out of the cross product of tangent and normal, but how can I find the normal of a 3D vector?
reedbeta at November 3rd, 2011 12:38 — #10
Depending on your paths you can often use a constant vector like (0, 0, 1) for the up-vector. (It doesn't need to be exactly perpendicular to the tangent; the matrix function will orthogonalize everything.) If you have segments going straight up or down this will break, so you'll have to use a different up-vector for those.
When using splines, another possibility is to define a normal vector using the second derivative of the curve; see here for details. The trouble with this is it may be discontinuous from one spline segment to the next, and it will fail on a straight-line segment since the second derivative will be zero.