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 › getting the direction of a moving point
Page Index Toggle Pages: 1
getting the direction of a moving point (Read 1287 times)
getting the direction of a moving point
Jan 31st, 2009, 7:39pm
 
Hi, ive got a question, hope you can help me.

lets say i got a moving point, particle or whatever and want it to draw a line when it moves but the line should always draw a thick line. so when the point moves up everything is fine but when it moves sidesways i just get a thin line. So it looks "Kalligraphic".
So i have to rotate the line in a direction so that it always draws a thick line...but how would i do that? do i have to compare the actual position with the last postion? Thank you!
Re: getting the direction of a moving point
Reply #1 - Feb 1st, 2009, 10:10am
 
Yes.

But showing how you draw the line might help us in understanding your issue.
Re: getting the direction of a moving point
Reply #2 - Feb 1st, 2009, 10:59am
 
Sorry. I guess this would be a good example. cause im working with particles too using traer physics.
so the line should rotate somehow that it always draws a thick line. Thank you for your help PhiLho.



import traer.physics.*;

Particle mouse, b;
ParticleSystem physics;

void setup()
{
 size( 400, 400 );
 frameRate( 24 );
 smooth();
 ellipseMode( CENTER );
 noStroke();
 noCursor();

 physics = new ParticleSystem( 0, 0.1 );
 mouse = physics.makeParticle();
 mouse.makeFixed();
 b = physics.makeParticle( 1.0, random( 0, width ), random( 0, height ), 0 );


 physics.makeAttraction( mouse, b, 10000, 10 );
}

void draw()
{
 mouse.moveTo( mouseX, mouseY, 0 );
 handleBoundaryCollisions( b );
 physics.tick();

 // background( 255 );

 fill( 255, 0, 0 );
 ellipse( mouse.position().x(), mouse.position().y(),  5,  5 );


 fill( 0, 255, 0 );
 stroke(0);
 strokeWeight(2);
 line(b.position().x()-10, b.position().y(),b.position().x()+10, b.position().y());
 noStroke();


}

// really basic collision strategy:
void handleBoundaryCollisions( Particle p )
{
 if ( p.position().x() < 0 || p.position().x() > width )
   p.setVelocity( -0.9*p.velocity().x(), p.velocity().y(), 0 );
 if ( p.position().y() < 0 || p.position().y() > height )
   p.setVelocity( p.velocity().x(), -0.9*p.velocity().y(), 0 );
 p.moveTo( constrain( p.position().x(), 0, width ), constrain( p.position().y(), 0, height ), 0 );
}

Re: getting the direction of a moving point
Reply #3 - Feb 1st, 2009, 11:11am
 
No need for matrix rotation, I think.
A simple change can be to add:
float prevX, prevY;
before setup()
and to change the line call to:
 line(prevX, prevY, b.position().x(), b.position().y());
 prevX = b.position().x(); prevY = b.position().y();


Might need some little refinements (avoiding initial draw to 0,0, limiting length of line or making it constant...), but that's the base idea.
Re: getting the direction of a moving point
Reply #4 - Feb 1st, 2009, 11:57am
 
Thats cool, i never thought about this solution.
But the line was just an example for some more complex brushes. Do you have any other tipps if it would look like this ?

import traer.physics.*;

Particle mouse, b;
ParticleSystem physics;

void setup()
{
 size( 400, 400 );
 frameRate( 24 );
 smooth();
 ellipseMode( CENTER );
 noStroke();
 noCursor();

 physics = new ParticleSystem( 0, 0.1 );
 mouse = physics.makeParticle();
 mouse.makeFixed();
 b = physics.makeParticle( 1.0, random( 0, width ), random( 0, height ), 0 );


 physics.makeAttraction( mouse, b, 10000, 10 );
}

void draw()
{
 mouse.moveTo( mouseX, mouseY, 0 );
 handleBoundaryCollisions( b );
 physics.tick();

 // background( 255 );

 fill( 255, 0, 0 );
 ellipse( mouse.position().x(), mouse.position().y(),  5,  5 );



 stroke(0);
 strokeWeight(1);
 line(b.position().x()-10, b.position().y(),b.position().x()+10, b.position().y());
 fill(244,0,0);
 ellipse(b.position().x()-10, b.position().y(),3,3);
 ellipse(b.position().x()+10, b.position().y(),3,3);
 noStroke();


}

// really basic collision strategy:
void handleBoundaryCollisions( Particle p )
{
 if ( p.position().x() < 0 || p.position().x() > width )
   p.setVelocity( -0.9*p.velocity().x(), p.velocity().y(), 0 );
 if ( p.position().y() < 0 || p.position().y() > height )
   p.setVelocity( p.velocity().x(), -0.9*p.velocity().y(), 0 );
 p.moveTo( constrain( p.position().x(), 0, width ), constrain( p.position().y(), 0, height ), 0 );  
}

Re: getting the direction of a moving point
Reply #5 - Feb 1st, 2009, 2:28pm
 
Code:
  stroke(0);
 strokeWeight(1);
 float x = b.position().x();
 float y = b.position().y();
 PVector v = new PVector(x - prevX, y - prevY);
 v.normalize();
 v.mult(20);
 line(x + v.x, y + v.y, x, y);
 fill(244,0,0);
 ellipse(x + v.x, y + v.y,3,3);
 ellipse(x, y,3,3);
 noStroke();
 prevX = x; prevY = y;

But indeed, as the shape gets more complex, using pushMatrix, rotate and popMatrix might be more usable... Smiley

I got:
Code:
float prevX, prevY;
PVector xAxis = new PVector(1, 0);

void setup()
[...]
// In draw()
 float x = b.position().x();
 float y = b.position().y();
 drawVector(x, y, new PVector(x - prevX, y - prevY));
 prevX = x; prevY = y;
}

void drawVector(float x, float y, PVector v)
{
pushMatrix();
float a = PVector.angleBetween(v, xAxis);
if (v.y < 0)
{
a = TWO_PI - a;
}
translate(x, y);
rotate(a);

stroke(0);
strokeWeight(1);
line(0, 0, 20, 0);
fill(244, 0, 0);
ellipse(0, 0, 3, 3);
ellipse(20, 0, 3, 3);
popMatrix();
}

Not 100% sure about my maths, but it behaves almost correctly... Smiley
[EDIT] I loose some information with angleBetween, having an angle between 0 and PI (which make sense, somehow), not between 0 and TWO_PI.
Sometime, the shape is perpendicular to the trajectory, not sure how to fix that yet.
[EDIT] I finally got it right, the fix is the test on sign of y.
Re: getting the direction of a moving point
Reply #6 - Feb 1st, 2009, 11:00pm
 
That looks pretty cool. I will take some time tomorrow and look at the code to understand what the math behind it is. So i also understand it this time Smiley thank you!
Re: getting the direction of a moving point
Reply #7 - Feb 6th, 2009, 7:20pm
 
PhiLho, i spend some time trying to understand. its working great. I guess i would have never come up with this solution. But now i know how to do it.
Thanks again!
Re: getting the direction of a moving point
Reply #8 - Feb 6th, 2009, 9:45pm
 
I am glad it was useful, I learned a bit while doing it.
For the record, I made a little sketch to study the angle given by angleBetween:
Code:
PVector xAxis = new PVector(1, 0);

float ox, oy;
float px, py;

void setup()
{
size(400, 400);
ox = width / 2; oy = height / 2;
PFont font = loadFont("AmericanTypewriter-24.vlw");
textFont(font, 12);
}

void draw()
{
background(#33AAFF);

DisplayAngle();
DrawVector();
}

void DisplayAngle()
{
PVector v = new PVector(mouseX - ox, mouseY - oy);
float rawAngle = PVector.angleBetween(v, xAxis);
float angle = rawAngle;
if (v.y < 0)
{
angle = TWO_PI - angle;
}

pushMatrix();
translate(ox, oy);
rotate(angle);

stroke(#000055);
strokeWeight(5);
line(0, 0, 170, 0);
fill(#000099);
ellipse(170, 0, 7, 7);
popMatrix();

text("Angle C: " + f(rawAngle) + " " + f(rawAngle / PI) +
" -> " + f(angle) + " " + f(angle / PI), 0, 380);
}

void DrawVector()
{
if (pmouseX != mouseX) px = pmouseX;
if (pmouseY != mouseY) py = pmouseY;
float dx = mouseX - px;
float dy = mouseY - py;
PVector v = new PVector(dx, dy);
float rawAngle = PVector.angleBetween(v, xAxis);
float angle = rawAngle;
if (v.y < 0)
{
angle = TWO_PI - angle;
}
pushMatrix();
translate(mouseX, mouseY);
rotate(angle);

stroke(#000066);
strokeWeight(3);
line(0, 0, 100, 0);
fill(#00FF00);
ellipse(0, 0, 7, 7);
fill(#008800);
ellipse(100, 0, 5, 5);
popMatrix();

text("Angle V: " + f(rawAngle) + " " + f(rawAngle / PI) +
" -> " + f(angle) + " " + f(angle / PI), 0, 330);
text("d: " + f(dx) + " " + f(dy), 0, 350);
}

String f(float f)
{
return String.format("%3.2f", f);
}
Re: getting the direction of a moving point
Reply #9 - Feb 7th, 2009, 1:42am
 
So you want to draw a line perpendicular to the particle's movement?  If so, there's an easy identity for rotating by 90-degrees: swap both and negate one of x,y.  For example, assuming you want a line 10 units off both sides:

Vector3D p = b.position();
Vector3D v = b.velocity().unit().multiplyBy(10);
line(p.x()-v.y(), p.y()+v.x(), p.x()+v.y(), p.y()-v.x());

hth
Page Index Toggle Pages: 1