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 › repulsion + keeping distance between points
Page Index Toggle Pages: 1
repulsion + keeping distance between points (Read 1044 times)
repulsion + keeping distance between points
Apr 8th, 2010, 6:28am
 
What I want to do is;

1. points are repelled by mouse pointer
2. then, points always keep the same distance between them.
   (no stretch)


So the points will be dynamic. a movement of one point influence to movements of the other points.

The problem is it is really hard for me to get the 2nd part.
So I am very pleased if anyone can tell me how to achieve it.


Code:

int screen_width   =  1000 ;  
int screen_height  =   800 ;

int m_rad  = 200;            // mouse pointer circle radius

float av     =  0.05 ;         // accelation value


//points
int p_number = 50 ;      // points number
int p_dist     = 10 ;      // distance between points

int p_x0  = 250 ;                     // begining point (x,y)
int p_y0  = 400 ;

PVector[] p = new PVector[p_number];



void setup()
{    
 size(screen_width, screen_height);    
 background(255);

 //points position  
 for(int i=0; i < p_number; i++)
 {    
   p[i] = new PVector(p_x0 + p_dist*i, p_y0) ;
 }
   
}



void draw()
{  
 background(255);  
 smooth();
 
 //point position
 for( int i = 0; i < p_number; i++ )
 {
   // between point and mouse         
   float angleA     = atan2( p[i].y - mouseY, p[i].x - mouseX);      
   float distanceA  = dist( p[i].x, p[i].y, mouseX, mouseY );      
   float moveA      = m_rad - distanceA ;
   
   if(distanceA < m_rad)
   {
     p[i].x += moveA * cos(angleA)  * av ;
     p[i].y += moveA * sin(angleA)  * av ;      
   }    
 }  
   
 //points and mouse pointer
 stroke(100);    
 strokeWeight(3);
 for(int i=0; i < p_number; i++)
 {  
   point(p[i].x, p[i].y);
 }
 
 noFill();  
 stroke(200);
 strokeWeight(1);
 ellipse(mouseX, mouseY, m_rad*2, m_rad*2);
 
}









Re: repulsion + keeping distance between points
Reply #1 - Apr 8th, 2010, 8:16am
 
Jun wrote on Apr 8th, 2010, 6:28am:
points always keep the same distance between them.

Not sure it is actually possible. Well, it is, it implies the points make a rigid structure, ie. a fixed shape...
Another way to do that (in a less rigid way) is to use libraries like Traer Physics.
Re: repulsion + keeping distance between points
Reply #2 - Apr 8th, 2010, 9:48am
 
I don't think 2 is physically possible.

If you're saying all the points must remain the exact same distance from each other, then that's not possible in 2 dimensions for any more than 3 points.

If you're saying they have to remain at the same distance form each other that they started at, then that's going to be a rigid shape, and it'll move as a whole without changing shape at all.
Re: repulsion + keeping distance between points
Reply #3 - Apr 8th, 2010, 10:33am
 
Thank you for giving me some advices.


Random_Arboretum by Traer Physics is similar to part 2.
http://www.cs.princeton.edu/~traer/physics/random_arboretum/index.html


Actually I want a fluid line defined by points.

The movement I want is just as same as in physical world, like when you push a cord with a disk on a surface, the shape of the cord changes fluidly, pushed by the disk.

In this situation, the disk is a mouse pointer and the cord is a line.
(not rigid)


Re: repulsion + keeping distance between points
Reply #4 - Apr 8th, 2010, 4:57pm
 
Dunno if this is what y want:

Code:
int screen_width   =  1000 ;  
int screen_height  =   800 ;

int m_rad  = 200; // mouse pointer circle radius

float av     =  0.05 ;   // accelation value

//points
int p_number = 50 ; // points number
int p_dist     = 10 ; // distance between points

int p_x0  = 250 ;   // begining point (x,y)
int p_y0  = 400 ;

PVector[] p = new PVector[p_number];

void setup()
{    
 size(screen_width, screen_height);    
 background(255);

 //points position  
 for(int i=0; i < p_number; i++)
 {    
   p[i] = new PVector(p_x0 + p_dist*i, p_y0) ;
 }
   
}

void draw()
{  
 background(255);  
 smooth();
 
 //points and mouse pointer
 stroke(100);    
 strokeWeight(3);
 for(int i=0; i < p_number; i++)
 {  
   point(p[i].x, p[i].y);
 }
 
 noFill();  
 stroke(200);
 strokeWeight(1);
 ellipse(mouseX, mouseY, m_rad*2, m_rad*2);
 
 for (int j=15;--j>0;) { // We need to do this a few times
 
 //point position
 for( int i = 0; i < p_number; i++ )
 {
   // between point and mouse    
   float angleA     = atan2( p[i].y - mouseY, p[i].x - mouseX);
   float distanceA  = dist( p[i].x, p[i].y, mouseX, mouseY );
   float moveA = m_rad - distanceA ;
   
   if(distanceA < m_rad)
   {
p[i].x += moveA * cos(angleA)  * av ;
p[i].y += moveA * sin(angleA)  * av ;
   }    
 }
 
 for (int i=p.length;--i>1;) { //Loop through points
   PVector p1=p[i]; //First
   PVector p2=p[i-1]; // Second, 1-point distance
   PVector p3=p[i-2]; // Third, 2-points distance
   keepDist(p1,p2,p_dist); //Keep distance between 1-2
   keepDist(p2,p3,p_dist); //Kepp distance between 2-3
   keepDist(p1,p3,p_dist*2); //Keep distance(double) between 1-3;
 }
 }
}
// The infamous keepdist routine. Essentially relaxation.
 void keepDist(PVector p1, PVector p2, float D) {
   float dx,dy,dz,lx,ly,lz,L;
dx=p2.x-p1.x;
dy=p2.y-p1.y;
dz=p2.z-p1.z;
L = sqrt(dx*dx+dy*dy+dz*dz);
L=.5*(1-(D/L));
lx=L*dx;
ly=L*dy;
lz=L*dz;
p1.x+=lx;
p1.y+=ly;
p1.z+=lz;
p2.x-=lx;
p2.y-=ly;
p2.z-=lz;
 }


Ive added essentially a relaxation loop to keep the distance between the points.
Or you could use a physics/point-spring solver to make your life easier prolly...
Re: repulsion + keeping distance between points
Reply #5 - Apr 9th, 2010, 6:04am
 
this is exactly what I want !!

thank you very much for your kindness Smiley

Page Index Toggle Pages: 1