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

Extend curve to tube surface (part 2)

Started by nkint Sep 4, 2010 at 6:13 AM 1 replies 1.1k views
Original Post
nkint
nkint
hi guys
i tried to reply this thread:
Extend curve to tube surface (part 1)
but seems not working anymore (?)

by the way, bit summary:
i have a curve (a bezier, but for tests and sketches i'm using a torus knot for semplicity) as a list of points, and i want to make a tubolar surface over it.

for that i have to find a frame, that is composed by 3 vectors: tangent, binormal and normal, in each point.
for that user jyk and apatriarca advice me to a parallel transform frame, good thecnique. it works!
it consists in calculate the first frame in first point and rotate it follow rotation angle of tangents.

i've found good reference:
Parallel Transport Approach to Curve Framing by Hanson and Ma
Game Programming Gems 2, The Parallel Transport Frame

in this previous post:
http://www.gamedev.net/community/forums/topic.asp?topic_id=577287


BUT:

#1 - find the first frame is a problem, i used approximations of frenet frame.
#2 - nowhere in reference i found that i need to recalculate cross product to find normal and binormals (!! how this is possible?? by the way thanks apatriarca you show me the way in last post)
#3 - in the end.. i found normal and binormal correctly but there was a big problem:
normals was switched: one directed inside, one outside.
i have to take the normal in previous frame but change it signs.
why???

here is my code, in pseudojava, hope this will be usefull for someone in future:

Vec3D points[]; // curve point listVec3D tangents[];Vec3D binormals[];Vec3D normals[];void calculateFrames() {  // first frame, needed by parallel transport frame approach  // frenet method is used.  // __approximations__ of tangents  Vec3D p0, p1, b;  p0 = points[0];  p1 = points[1];  tangents[0] = getTangentBetweenTwoPoint(p0, p1);  p0 = points[1];  p1 = points[2];  tangents[1] = getTangentBetweenTwoPoint(p0, p1);  b = tangents[0].cross(tangents[1]);  b.normalize();  binormals[0] = b;  normals[0] = b.cross(tangents[0]);  // all tangents, needed for p.t.f.  // again, __approximations__  // #1  for(int i=1; i<100-1; i++) {    p0 = points;    p1 = points[i+1];    tangents = getTangentBetweenTwoPoint(p0, p1);  }  // p.t.f approach:  Vec3D old_normal;  for(int i=1; i<100-2; i++) {    p0 = tangents;    p1 = tangents[i+1];    // this is what is called A in game programming gems    // and B in Hanson and Ma article    b = p0.cross(p1);    b.normalize();    // normals    theta = acos(p0.dot(p1));    old_normal = normals[i-1];    old_normal.normalize();    old_normal.rotateAroundAxis(b,theta);    // here switching signs. no reference, no understanding,     // empirical method founded for random choice.    // #3    old_normal.x = -old_normal.x;    old_normal.y = -old_normal.y;    old_normal.z = -old_normal.z;    // ma questi due ulteriori cross da dove vengono fuori?!    // #2    binormals = tangents.cross(old_normal);    normals = tangents.cross(binormals);    println("it should be PI/2: "+PI/2);    //    println(Vec3D.angleBetween(binormals, tangents));    //    println(Vec3D.angleBetween(normals, tangents));    //    println(Vec3D.angleBetween(normals, binormals));        // assertation tests here  }}


i hope this helps, strange that there is nowhere tutorials about this, it is a tech quite used for all tubolar-res

[Edited by - nkint on September 4, 2010 6:29:04 AM]
Zakwayda
Zakwayda
I didn't quite follow all of the details of your post, but if you're just looking for a method for generating an arbitrary initial frame given only a tangent vector, I'd recommend the method described in this thread.
nkint
nkint
thanks for replay,
good solution! i'll try to implement it.

but the things in which i'm interesting more is about switched normals.
ohu, my code for now is works perfectly, it's only a question of understanding why..

i don't understand because, in parallel transpot frame approach, i have to
take the normal of the last frame BUT switchs it signs after rotation,

old_normal = normals[i-1];old_normal.normalize();old_normal.rotateAroundAxis(b,theta);old_normal.x = -old_normal.x;old_normal.y = -old_normal.y;old_normal.z = -old_normal.z;


well.. if you don't want to follow details no problem, code for now works perfectly,
i'm really thank for you help!

Topic Locked

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

Sign in to reply to this topic.