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 › Normalizing PVectors
Page Index Toggle Pages: 1
Normalizing PVectors (Read 906 times)
Normalizing PVectors
Mar 2nd, 2010, 5:29pm
 
hi
i'm a bit confused about normalizing PVectors. I am rotating objects by adding a speed vector, then normalizing it to constrain their movement. but the objects come to a halt after a few seconds of movement. though the variables are still showing movement. everything is happening in the update() function.

Code:

class Circs{
float x, y, z, angle;
float sphereSize;
int me;
PVector pos, speed, reverseSpeed;

Circs(int _me, float _angle) {
angle = _angle;
me = _me;
sphereSize= random(15, 30);
float xspeed =random(-5, 5);
//xspeed = constrain(abs(xspeed),0.5,4);
float yspeed =random(-4, 4);
//yspeed = constrain(abs(yspeed),0.5,4);
float zspeed =random(-4, 4);
// zspeed = constrain(abs(zspeed),0.5,4);
speed = new PVector (xspeed, yspeed, zspeed);

x=cos(angle)*(radius/2+sphereSize/2);
y=sin(angle)*(radius/2+sphereSize/2);
z= random(-radius/2, radius/2);

pos = new PVector (x,y,z);
}

void draw(){
update();
fill(255);

pushMatrix();
translate(pos.x, pos.y, pos.z);
sphere(sphereSize);
popMatrix();

}

void update(){
pos.add(speed);
pos.normalize();
pos.mult(radius/2);
println ("x: " + pos.x + "y: " + pos.y + "z: " + pos.z);
println ("speedx: " + speed.x + " speedy: " + speed.y + " speedz: " + speed.z );
}

}




Re: Normalizing PVectors
Reply #1 - Mar 3rd, 2010, 1:50am
 
Could you post the whole source, so that one can easily test it? The snipped you've posted seems to miss the "radius" variable, and it would be good to see how you use the object in the draw() function...
Re: Normalizing PVectors
Reply #2 - Mar 3rd, 2010, 5:05am
 
ok, sorry, here's the whole shebang:
Code:


//import processing.opengl.*;

float radius = 200;
int balls = 15;

Circs[] circs;

void setup(){
size(640, 480, P3D);
circs = new Circs[balls];
float ang = 0;
for(int i=0; i< balls; i++){
circs[i] = new Circs(i, ang);
ang+=radians(random(180));
}
noStroke();
sphereDetail(8);
}
void draw(){
background(255);
lights();
translate(width/2,height/2);
//rotateY(radians(frameCount));
//rotateX(radians(frameCount));
sphereDetail(80, 80);
sphere(radius/2);
sphereDetail(15,15);
for (int i=0; i<circs.length; i++){
circs[i].draw();
}

}

void mousePressed(){
println("frameRate: "+frameRate);
}

class Circs{
float x, y, z, angle;
float sphereSize;
int me;
PVector pos, speed, reverseSpeed;

Circs(int _me, float _angle) {
angle = _angle;
me = _me;
sphereSize= random(15, 30);
float xspeed =random(-5, 5);
//xspeed = constrain(abs(xspeed),0.5,4);
float yspeed =random(-4, 4);
//yspeed = constrain(abs(yspeed),0.5,4);
float zspeed =random(-4, 4);
// zspeed = constrain(abs(zspeed),0.5,4);
speed = new PVector (xspeed, yspeed, zspeed);

x=cos(angle)*(radius/2+sphereSize/2);
y=sin(angle)*(radius/2+sphereSize/2);
z= random(-radius/2, radius/2);

pos = new PVector (x,y,z);
}

void draw(){
update();
fill(255);

pushMatrix();
translate(pos.x, pos.y, pos.z);
sphere(sphereSize);
popMatrix();

}

void update(){
pos.add(speed);
pos.normalize();
pos.mult(radius/2);
println ("x: " + pos.x + "y: " + pos.y + "z: " + pos.z);
println ("speedx: " + speed.x + " speedy: " + speed.y + " speedz: " + speed.z );
}

}





Re: Normalizing PVectors
Reply #3 - Mar 3rd, 2010, 6:32am
 
what happens is that the more iterations you have the more the position becomes a multiple of the speed vector so effectively it's trying to move away from the centre but is being normalised back to the surface.

can't think of a way to get around this at the moment.
Re: Normalizing PVectors
Reply #4 - Mar 3rd, 2010, 7:59am
 
You could also look at it from a vector-calculation point of view.
If you print out the cross-prodcut of your position and velocity vectors by
println("cross:"+pos.cross(speed));
you will see that this vector is getting smaller and smaller. Now, the cross-product of vector a with vector b is a vector perpendicular to the plane given by the both vectors and with a length calculated as
|a| * |b| * sin(phi<ab>)  with | | beeing the length and phi<> beeing the angle between the vectors.
The vector going "smaller and smaller" means that a & b (or pos & velocity) become more and more parallel as you continue which is exactly what koggy was posting...

What you want to achieve is a "speedvector" which is always normal to the direction of the position vector.
Re: Normalizing PVectors
Reply #5 - Mar 3rd, 2010, 8:19am
 
The following sketch will help you to understand what you are doing wrong. It is basically the same idea of "adding velocity + normalize" just shown in 2D with a line in white (Pos) and velocity line (red).
You see how successive adding & normalizing "parallelize" the Position vector.
Code:

PVector Pos,Vel;
int col;
float radius=100;
void setup()
{
 size(300,300);
 background(0);
 col=255;
 Pos = new PVector(40,30);
 Pos.normalize();
 Pos.mult(radius);
 Vel = new PVector(40,-20);
}

void draw()
{
 col--;
 stroke(col);
 translate(width/2,height/2);
 line(0,0,Pos.x,Pos.y);
 Pos.add(Vel);
 Pos.normalize();
 Pos.mult(radius);
 stroke(col,0,0);
 line(Pos.x,Pos.y,Pos.x+Vel.x,Pos.y+Vel.y);
}
Re: Normalizing PVectors
Reply #6 - Mar 4th, 2010, 2:06am
 
Since you are constraining movement to the surface of a sphere then rather than defining the velocity as a change in XYZ position, it is probably better to consider the velocity as the rate of change in longitude an latitude.

There would be no need to record the XYZ position of the sphere rather this would be calculated from the angles for latitude and longitude and these angles can be simply incremented/decremented each update according to the velocity..

Are you wanting to rotate the small spheres to face the direction of movement? That would add a little more work.

Page Index Toggle Pages: 1