Skip to main content
GameDev.net gamedev.net
🔒 Locked

Extend curve to tube surface

Started by nkint Jul 22, 2010 at 5:53 AM 6 replies 2.4k views
Original Post
nkint
nkint
hi guys
i'm doing a project for geometry exams at university,
with java.

i've done a curve.
it's a helix with, as trunk, a bezier curve, (but this is not important).
now i have ah array of Point3D (my own class with x,y,z).

if i render it i have a wire curve in the space. ok, great.

now i want to expand it, not only a point-thickness
but a real tube.

like a toroid is a tube of a circle.

can you help me? some advice? some place where i can find something similar?
(examples, articles, etc)

(for now no render stuffs, no light, no zbuffer or backface culling.)

thanks in advance, i hope i've wrote understandable english
apatriarca
apatriarca
Let c(t) be the equation of your curve and {T(t), N(t), B(t)} the corresponding Frenet frame. You can then define your tubular surface as

s(t, u) = c(t) + r * (cos(u) * N(t) + sin(u) * B(t))

In the case of a circle, you have for example
c(t) = (cos(t), sin(t), 0)

T(t) = (-sin(t), cos(t), 0)
N(t) = (-cos(t), -sin(t), 0)
B(t) = (0, 0, 1)

s(t, u) = (cos(t)*(1 - r*cos(u)), sin(t)*(1 - r*cos(u)), r*sin(u))

which is a torus.
nkint
nkint
ok great, supercool, really thanks
i thought it was more complicated.

1) parameter u is from 0 to PI, cause it is a parameter of the circumference of the tube.

2) by the way, if i change the curve i have to change T(t), N(t), B(t).
if i maintain my curve of jelix with a bezier trunk is it ok. but i want also change the trunk, not only bezier but also.. i don't know, like http://www-dimat.unipv.it/PorteAperte/I-16.JPG or something elsei have to recalculate manually 1° and 2° derivate for fernet frame.

if i have all the point of c(t) there is a way to authomathically find 1° and 2° derivates for t,n,b ?

3) in opengl like mode i have to draw my surface with quad strip, right?
some kind ok order?

--------------------------python pseudocode
t, u = 0,0

beginShape(QUAD_STRIP)

circ1 = [s(0,u) for u in range(0,PI, PI/100)]

for t in range(1,11/100):
__circ2 = [s(t,u) for u in range(0,PI, PI/100)]
____for i in range(0,100, 2):

______vertex(circ1.x, circ1.y, circ1.x)
______vertex(circ1[i+1].x, circ1[i+1].y, circ1[i+1].x)
______vertex(circ2.x, circ2.y, circ2.x)
______vertex(circ2[i+1].x, circ2[i+1].y, circ2[i+1].x)

____circ1 = circ2

endShape()

[Edited by - nkint on July 22, 2010 1:49:26 PM]
Zakwayda
Zakwayda
This was also recently discussed here.
Quote:
3) in opengl like mode i have to draw my surface with quad strip, right?
some kind ok order?
It would probably make more sense to use an indexed triangle mesh (or individual triangles, if you're rendering in immediate mode).
nkint
nkint
wow..
great.

i see the solution but i havn't really understand.

the fact is: i have only points of a generic curve.
i had to find tangent normal and binormal vector for frenet frame.

the challenge is get derivate1 and derivate2

one approch is:

code from()

Vector3 pos
Vector3 posNext
//pos e posNext are given

Vector3 d1 = posNext - pos;
//derivate prime!! ok, great

Vector3 T = Vector3.Normalize(d1);
//and so, the tangent. now, i need the derivate 2° ?

Vector3 N = d1.MinAxis;
// ??? (*)

Vector3 B = Vector3.Normalize(Vector3.Cross(T, N));


now i have the plane for position the circle
with the center in pos,
with tangent in t, on plane between n and b.

i can aplly formula
s(t, u) = c(t) + r * (cos(u) * N(t) + sin(u) * B(t))
from apatriarca.

but.. what is d1.MinAxis?

(*) this one?
blic int MinAxis()
{
return X < Y ? (X < Z ? 0 : 2) : (Y < Z ? 1 : 2);
}
from http://svn.assembla.com/svn/wolxna/XnaDevRu.BulletX/LinearMath/Vector3.cs

but what this is?

----------------------------------------

but 2° derivate?
how can i do it?
with another iteration, instead curve points use tangent points?

----------------------------------------
another approach founded here: http://www.gamedev.net/community/forums/topic.asp?topic_id=378061

i know the tangent and this it's all.
the plane is not ge between normal and binormal but with a rotation.
that thread explain how to find the rotation matrix.

but in the case i do not use local coordinate, right?





sorry for my poor math knowledge
Zakwayda
Zakwayda
If your sample points are dense enough, you can just approximate the first derivative as the difference between one point and the next (as you alluded to in your post). Or, you can compute the derivative from the original Bezier curve (which isn't hard).

If you then make use of the parallel transport frame, you won't need to worry about the second derivative. Just compute an arbitrary initial frame based on the direction of motion at the beginning of the curve, and then apply a relative rotation at each step to keep the frame aligned with the curve. (Again, see the thread I linked to earlier.)
nkint
nkint
jyk said: "Or, you can compute the derivative from the original Bezier curve (which isn't hard)."
no, it's not hard. but i don't have a normal bezier.

i have an helix that goes with the trunk of a bezier.
the equation of my special curve is:
p(t) = r*cos(t*u)*_n_ + r*sin(t*u) *_b_ + k*t*_t_
where r and k are parater of the helix. u is a another angula parameter,
and _t_, _n_ and _b_ are tagnet, normal, binormal of the bezier that is the trunk of my special final helix.


i want to make tubolar surface of p(t).
so i need the frenet frame of p(t). i think it's bit hard get this second derivates.
and if it's not hard is no flexible way: if the trunk change with a not more bezier but.. i don't what, simple parabol or others, i have to do too much recalculus.


ok, i understan the approximation of the 1° derivates (my points are dense enough), but there is a way for approximate the second der?
there is a way? for me it is cleaner approach.


i think for now i'll try the parallel transport fram, that is tricky. i re-read the links and they are good, i think i can use this thecnique, even if i would prefer to have method for 1° and 2° deriv. for an arbitrary curves.


by the way, what is "Vector3 N = d1.MinAxis;" that use the code of xnt i posted?


thanks to all, i never seen a forum with hardmath and lowcoders as this one!
apatriarca
apatriarca
Quote:
Original post by nkint
i have an helix that goes with the trunk of a bezier.
the equation of my special curve is:
p(t) = r*cos(t*u)*_n_ + r*sin(t*u) *_b_ + k*t*_t_
where r and k are parater of the helix. u is a another angula parameter,
and _t_, _n_ and _b_ are tagnet, normal, binormal of the bezier that is the trunk of my special final helix.

i want to make tubolar surface of p(t).
so i need the frenet frame of p(t). i think it's bit hard get this second derivates.
and if it's not hard is no flexible way: if the trunk change with a not more bezier but.. i don't what, simple parabol or others, i have to do too much recalculus.

With this method you have to recalculate everything each time you change the original curve. It may also be impractical to calculate the Frenet frame in this case. The first derivative is already quite complicated.

Quote:

ok, i understan the approximation of the 1° derivates (my points are dense enough), but there is a way for approximate the second der?
there is a way? for me it is cleaner approach.

i think for now i'll try the parallel transport fram, that is tricky. i re-read the links and they are good, i think i can use this thecnique, even if i would prefer to have method for 1° and 2° deriv. for an arbitrary curves.

Actually, the parallel transport method is more general than the method based on Frenet frames. Indeed, the method based on Frenet frames only works with C^2 curves c which satisfy ||c''(t)|| != 0 for each t. The parallel transport method only requires the ability to define a "tangent vector".

The second derivative can be calculated from the first derivative as you calculated the first derivative from the position. So you can simply use the difference between the next derivative and the current one. It is actually similar to what is done in the parallel transport method. In that method the binormal is calculated using the formula:
B = cross(T_{i}, T_{i+1})
while it is generally calculated as
B = normalize(cross(c'(t), c''(t)))
That is calculated using the approximation c''(t) = c'(t + 1) - c'(t) as follows
cross(c'(t_i), c''(t_i)) =
= ||c'(t_i)|| cross(T_i, c''(t_i)) =
= ||c'(t_i)|| cross(T_i, c'(t_{i+1}) - c'(t_i)) =
= ||c'(t_i)|| (cross(T_i, c'(t_{i+1})) - cross(T_i, c'(t_i))) =
= ||c'(t_i)|| ||c'(t_{i+1})|| cross(T_i, T_{i+1})
The normal is then calculated rotating it the same amount the tangent vector is rotated. Hope it make more sense now.

[Edited by - apatriarca on July 24, 2010 10:46:49 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.