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 & HelpSyntax Questions › rotateZ and X giving two PVectors in space
Page Index Toggle Pages: 1
rotateZ and X giving two PVectors in space (Read 1435 times)
rotateZ and X giving two PVectors in space
Jan 22nd, 2010, 3:58am
 
Hello everyone,
I got a question.

I am building a 3D tree made of cylinders. Cylinders are joined togheter via traer.physics springs.

I have a spring made of particles, and each couple of particles made the top and base center of my cylinder. the more the cylinders, the more the plant grows and it's random shape takes form.

   pushMatrix();
   rotateZ(atan2(????));
   rotateX(atan2(????));
   noStroke();
   beginShape(QUAD_STRIP);
   for (int i = 0; i < sides + 1; ++i) {
     vertex(topRadius*cos(angle), a.position().y(), topRadius*sin(angle));
     vertex(bottomRadius*cos(angle), b.position().y(), bottomRadius*sin(angle));
     angle += angleIncrement;
   }
   endShape();
   popMatrix();


I need to calculate what are the degrees of rotation of each new cylinder.
The base (x,y,z) of the cylinder is positioned at the coords of the 'b' particle and the top at the coords of 'a' particle.
Suppose (in general) i have point in space like PVector(0, 10, 0). That's the base of the cylinder. The next point (the top of my cylinder) should be placed at (12, 20, -6). The cylinder should then be rotated, tight?
How can i calculate the rotation?  Huh
Many thanks in advance.
Re: rotateZ and X giving two PVectors in space
Reply #1 - Jan 22nd, 2010, 5:22am
 
maybe with        
angleBetween()?
Re: rotateZ and X giving two PVectors in space
Reply #2 - Jan 22nd, 2010, 5:28am
 
Let point b be the desired base center, and point a be the desired top center.

First off, once the thing is rotated correctly, you can just translate it to where it needs to be (translate(b.x, b.y, b.z); ), so let's assume that the center of the base of the cylinder stays at (0,0,0) for now.

If that's where the center of the base stays, then the center of the top needs to end up at (a.x-b.x, a.y-b.y,a.z-b.z), right? Call this point c.

Now the height of the cylinder needs to be the distance between (0,0,0) and point c. Call this height h. You can get this easily ( dist(0,0,0, c.x, c.y, c.z); ), and scale your cylinder appropriately (scale(1,h,1); ).

Now instead of a whole cylinder, imagine just the line running down the center of the cylinder (the core of it, if you will). I don't know how you're drawing your cylinder, but I'll just assume that you draw the base in the xz-plane (so the core line goes from (0,0,0) to (0,h,0) ).

This line needs to be rotated around the z-axis a bit, and then rotated around the y-axis. Imagine the projections of the final position of the core line on the xy- and xz-planes. You can get these projections easily ( (c.x,c.y,0) and (c.x,0,c.z) ), and the angles these projections make with the x-axis determine how much you need to rotate things.

A little trig later, you get tan(angleToRotateZ) = c.y/c.x and tan(angleToRotateY) = c.z/c.x

Or you could skip the little trig and try something with atan2()...
Like, say, atan2( c.z, c.x ) and atan2( c.y, c.x )
Re: rotateZ and X giving two PVectors in space
Reply #3 - Jan 22nd, 2010, 5:46am
 
TfGuy44 thank you so much. very detailed explanation, tnx!
going to try this, and let you know.

Grazie!!!
Re: rotateZ and X giving two PVectors in space
Reply #4 - Jan 22nd, 2010, 12:12pm
 
So, did you get it working?
Re: rotateZ and X giving two PVectors in space
Reply #5 - Jan 25th, 2010, 1:29am
 
not yet, but let me prepare a reply with some images and the class, so you should better get what i need.

I'm quite near tho. and, i don't pretend you to do this job for me, absolutely. If you got time just point me in the direction.

...

Here it is the trunk. It is made of a set of cylinders and (for now) they are generated/positioned that way:

a) i add a new particle to the list. The new particle's coords are randomly picked form a set of the many point defined by a function wich randomly draws the coordinates of a semisphere whose center is placed at the same location of the parent particle (the one below the new one) and whose radius is a certain value (fixed)- it's tricky, but it's a sketch Huh This couple (and the next ones) of particle made a spring.

b) for each spring:

for ( int i = 0; i < physics.numberOfSprings(); ++i )
{
   Spring e = physics.getSpring( i );
   Particle a = e.getOneEnd();
   Particle b = e.getTheOtherEnd();

/*
get two particles coords and pass to the Cylinder class
70, 70 are the top and bottom radius
and a & b are used to retrieve the coords for the topRadius and    bottomRadius initial position
*/
   c = new Cylinder(70, 70, a, b);
   c.render();
}

c) the Cylinder class:
class Cylinder
{
float topRadius;
float bottomRadius;
int sides = 30;
Particle a;
Particle b;
 
 Cylinder(float _topRadius, float _bottomRadius, Particle _a, Particle _b)
 {
   a = _a;
   b = _b;
   topRadius =_topRadius;
   bottomRadius = _bottomRadius;
 }
 void render()
 {
   float angle = 0;
   float angleIncrement = TWO_PI / sides;
   pushMatrix();
   noStroke();
   beginShape(QUAD_STRIP);
   for (int i = 0; i < sides + 1; ++i) {
   vertex(a.position().x()+topRadius*cos(angle), a.position().y(), a.position().z()+ topRadius*sin(angle));
   vertex(b.position().x()+bottomRadius*cos(angle), b.position().y(), b.position().z()+ bottomRadius*sin(angle));
    angle += angleIncrement;
   }
   endShape();
   popMatrix();
 }
}

Using your trig system i cannot make them rotate properly.
Using just my intuition, i got the result you see in teh pictures, where each new cyclinder is positioned correctly, but not really rotated, but rather distorted.
I need them to be rotated.
That way i should be able to create some branch correctly rotated, and the magnetic force should avoid the branches to overlap.
That's the idea.
Re: rotateZ and X giving two PVectors in space
Reply #6 - Jan 25th, 2010, 4:17am
 
Bad news: I'm as stumped as you are!  Embarrassed Here's a simulation that's trying to show you how you can orientate a cylinder like I think you want. The trouble is, it doesn't work! Grr!

Quote:
/// Direction: W to show wireframe. S to toggle spinning.

// Tube variables
float ax = 3;
float ay = -3;
float az = 3;
float bx = 1;
float by = -2;
float bz = 4;
float radius = 3.0;
float cx;
float cy;
float cz;
float h;

// Not relevent to the tube, used for simulation
boolean wires = false;
boolean spin = true;
float rotY = 0.0;

void setup(){
  size(400, 400, P3D);
  noStroke();
  fill(255,0,0);
  wires = false;
  spin = true;
    
  cx = ax-bx;
  cy = ay-by;
  cz = az-bz;  
  h = dist(0,0,0,cx,cy,cz);
}

void draw(){
  pushMatrix();
  lights();
  background(0);
  translate(width/2.0, (height/4.0)*3.0);
  scale(40);
  rotateY(rotY);
  if(spin){rotY+=0.05;rotY%=360.0;}
  boundingBox(color(0,255,0)); // This green box is "normal" space.
  stroke(255,255,0);
  line(ax,ay,az,bx,by,bz);
  if(wires){stroke(255);noFill();}else{noStroke();fill(255);}  

  // Instead of fiddling with the tube, trying to move it to the right position in space...
  // we're going to leave the tube where it is and fiddle about with space itself!
   translate(bx,by,bz);
   rotateY(atan2(cz,cx));
   rotateZ(atan2(cy,cx)); // OH HOW I WISH THIS WORKED!
   scale(radius, h, radius);
   translate(0, -.5, 0);
   drawTube(); 

  boundingBox(color(255,0,0)); // This RED box shows the space the tube is in.
  stroke(255,0,255);
  line(0,-.5,0,0,.5,0); // Draw a purple line down the core of the tube.
  popMatrix();
}

void keyPressed(){
  if(key=='w'){wires=!wires;}
  if(key=='s'){spin=!spin;}
}

void drawTube(){drawTube(30);}
void drawTube(int detail) {
    float angle = 0;
    float angleIncrement = TWO_PI / detail;
    pushMatrix();
    beginShape(QUAD_STRIP);
    for (int i=0; i<detail+1; ++i) {
      vertex( cos(angle)/2.0, -.5, sin(angle)/2.0 );
      vertex( cos(angle)/2.0,  .5, sin(angle)/2.0 );
      angle += angleIncrement;
    }
    endShape();
    popMatrix();
  }

void boundingBox(color cBox){
  pushStyle();
  noFill();
  stroke(cBox);
  box(1);
  popStyle();
}



BUT: There is some good news. The above code will run fine by itself, meaning someone else can copy and paste this and run it without having to muck about with your classes or particles or anything else.

Hopefully someone *coughblindfishwehereareyou?cough* will probably spot what I'm doing wrong/correct it pretty quick. 100 points to whoever can get the purple line to align with the yellow line.

I'd keep at it, but it's 4AM here and I'm sure it's something blindingly obvious but I'm just too tired to look at this code any moZZZZZZ...
Re: rotateZ and X giving two PVectors in space
Reply #7 - Jan 25th, 2010, 5:15am
 
TfGuy44 i really appreciate your help!!!
I wish you a good night, and grazie mille!!!!

GC
Re: rotateZ and X giving two PVectors in space
Reply #8 - Jan 25th, 2010, 11:14am
 
the problem is those two atan2's (the second one should be an acos -- draw enough diagrams and you'll eventually see that the second angle varies after the first rotation) search web for 'spherical coordinates' for some useful insights.  essentially you need something like this to first get those coords:

float r = sqrt(cx*cx+cy*cy+cz*cz);
float theta = atan2(cy,cx);
float phi = acos(cz/r);

then apply them something like this:
translate(bx,by,bz);
rotateZ(theta);
rotateY(phi);
rotateX(-HALF_PI); // *

* i chose the "textbook" first two rotations, but i think that'll leave your desired extrusion axis (Y) perpendicular to where you want it, so this third rotation should fix that -- tho it might be + instead of -, i have a hard time keeping track of inverted y's and the backwards trig of processing ;-)   it should be workable with just 2 rots, but you'd have to sort out the proper order that aligns your axes where you want them on your own.

hth
Re: rotateZ and X giving two PVectors in space
Reply #9 - Jan 26th, 2010, 2:04am
 
IT WORKS!
Thank you very much. I can now continue my exploration.  Wink


That ended in a monster made of tentacles:
http://www.openprocessing.org/visuals/?visualID=7207

Well guys, now I know how to "rotateZ and X giving two PVectors in space".
Thanks, that will be very useful in future.
Page Index Toggle Pages: 1