We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › 3d rotation
Page Index Toggle Pages: 1
3d rotation (Read 1862 times)
3d rotation
Jun 21st, 2009, 2:10pm
 
Hello,

I have a problem with rotation. I have the solution in c++/opengl but I want to use P3D in processing to do the same thing. (I dont want to use opengl shapes coz I want to export it with an .STL exporter)

I want to draw cylinders in 3d by having 2 PVectors as the start and the end point. length is the distance between the PVectors. I have search the forum and the web (as you can see my code has many examples from the forum) with no luck.

C++/openGL
Code:
void mpee::renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)
{
   float vx = x2-x1;
   float vy = y2-y1;
   float vz = z2-z1;

   //handle the degenerate case of z1 == z2 with an approximation
   if(vz == 0)
       vz = .00000001;

   float v = sqrt( vx*vx + vy*vy + vz*vz );
   float ax = 57.2957795*acos( vz/v );
   if ( vz < 0.0 )
       ax = -ax;
   float rx = -vy*vz;
   float ry = vx*vz;
   glPushMatrix();

   //draw the cylinder body
   glTranslatef( x1,y1,z1 );
   glRotatef(ax, rx, ry, 0.0);
   gluQuadricOrientation(quadric,GLU_OUTSIDE);
   gluCylinder(quadric, radius, radius, v, subdivisions, 1);

   //draw the first cap
   gluQuadricOrientation(quadric,GLU_INSIDE);
   gluDisk( quadric, 0.0, radius, subdivisions, 1);
   glTranslatef( 0,0,v );

   //draw the second cap
   gluQuadricOrientation(quadric,GLU_OUTSIDE);
   gluDisk( quadric, 0.0, radius, subdivisions, 1);
   glPopMatrix();
}


and many attempts in processing:
Code:
   for( int i=1; i < renderPath.size(); i++ ) {
     DLAParticle p = (DLAParticle)renderPath.get(i);
     if(p.parent == null) break;

     DLAParticle p1 = p.parent;
     //stroke(5, 10, 50);
     fill(200,50,200,p.size+10);
     float h = p.pos.dist(p1.pos);
     float w = p.size;
     float ramt = TWO_PI/30.f;



     // test 1 ////////////
     float vx = p.pos.x-p1.pos.x;
     float vy = p.pos.y-p1.pos.y;
     float vz = p.pos.z-p1.pos.z;

     //handle the degenerate case of z1 == z2 with an approximation
     if(vz == 0)
       vz = .00000001;

     float v = sqrt( vx*vx + vy*vy + vz*vz );
     float ax = 57.2957795*acos( vz/v );

     if ( vz < 0.0 ) ax = -ax;

     float rx = -vy*vz;
     float ry = vx*vz;

     // test 2 ///////////////

     PVector location1 = new PVector(p.pos.x, p.pos.y, p.pos.z);
     PVector location2 = new PVector(p1.pos.x, p1.pos.y, p1.pos.z);
     PVector d = PVector.sub(location2, location1);
     PVector polar = cartesianToPolar(d);

     stroke(255,0,0);
     line(p.pos.x, p.pos.y, p.pos.z,p1.pos.x, p1.pos.y, p1.pos.z);
     stroke(0);
     
     pushMatrix();

     translate(location1.x, location1.y, location1.z);
     rotateY(polar.y);
     rotateZ(polar.z);
     //rotateZ(d.z);
     /////////
   
     
     // openGL
     //
     //gl.glPushMatrix();
     //gl.glTranslatef( p1.pos.x,p1.pos.y,p1.pos.z );
     //gl.glRotatef(ax, rx, ry, 0);
     //gl.glTranslatef( p1.pos.x,p1.pos.y,p1.pos.z );

     //rotateX(ax);
     //rotateY(ax);
     //translate(rx,ry,0.0f);
     //rotate(PVector.angleBetween(p.pos,p1.pos));


     beginShape(QUADS);
     for( float r = 0; r < TWO_PI; r += ramt )
     {
       vertex( cos(r)*w, -h, sin(r)*w );
       vertex( cos(r+ramt)*w, -h, sin(r+ramt)*w );
       vertex( cos(r+ramt)*w, h, sin(r+ramt)*w );
       vertex( cos(r)*w, h, sin(r)*w );
     }
     endShape();
     
     //gl.glPopMatrix();
     
     popMatrix();


   }



Cheesy  Shocked

give me a hand if you can please!

Tasos
Re: 3d rotation
Reply #1 - Jun 22nd, 2009, 8:13am
 
anyone?!?!  Lips Sealed Undecided Cry
Re: 3d rotation
Reply #2 - Jun 22nd, 2009, 1:44pm
 
would be easier to help if you'd pasted a full example so we can just cut and paste and run it.

anyway i think your problem is with
glRotatef(ax, rx, ry, 0.0);
which is a rotation of ax, around the vector rx, ry, 0 which doesn't have an equivalent (afaik) in processing.

that said, the opengl man page pretty much gives you the matrix for said transformation:
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rotate.html

i'm still slightly puzzled by "having 2 PVectors as the start and the end point". what about the radius? ah, ok, constant.
Re: 3d rotation
Reply #3 - Jun 22nd, 2009, 3:10pm
 
ok, this does the same thing
Code:

// from opengl manpage for glRotatef()
void rotate3d(float angle, float _x, float _y, float _z) {
float c = cos(angle);
float s = sin(angle);
// normalise
float m = mag(_x, _y, _z);
float x = _x / m;
float y = _y / m;
float z = _z / m;
applyMatrix(
x * x * (1 - c) + c, x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0,
y * x * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - x * s, 0,
x * z * (1 - c) - y * s, y * z * (1 - c) + x * s, z * z * (1 - c) + c, 0,
0, 0, 0, 1);
}


NOTE you need to get rid of the 57.26 in the ax calculation - it's converting radians to degrees but we want radians

float ax = acos(vz / v);

also, the cylinder, as per gluCylinder, needs to be drawn from with the base at z = 0 and top at z = len (where len is the distance between the two vectors (v)
Re: 3d rotation
Reply #4 - Jun 22nd, 2009, 3:11pm
 
ie

Code:

// lazy cylinder, circular in x and y, height = z, no caps
void cylinder(int divisions, float radius, float len) {
for (int i = 0 ; i < divisions ; i++) {
float angle1 = i * (TWO_PI / divisions);
line(radius * cos(angle1), radius * sin(angle1), 0,
radius * cos(angle1), radius * sin(angle1), len);
}
}
Page Index Toggle Pages: 1