Loading...
Logo
Processing Forum
Hi guys,

How can I update the script below in order to have multiple intersection points between the moving line and all other fixed ones?
I have a submission and I really need it , so I really appreciate your prompt answers.

this is my script (using processing.js examples):

int DONT_INTERSECT = 0;
int COLLINEAR = 1;
int DO_INTERSECT = 2;

float x =0, y=0;

void setup(){
  size(600,200);
  fill(255,0,0);
}

void draw(){

  int intersected;

  background(255);
  
  // lignes
  stroke(0);
  
  // line fixe
  //line(20,height/2, width-20, (height/2)-20);  PROCESSING EXAMPLE
  line(width-width, height-(height/3), width,height-(height/3)); //Horizon Line
  line(width/5,height/5,width,height-(height/3));                 //Line1
  line(width/5,height/5,width-(width/5),height-(height/3));       //Line2
  line(width/5,height/5,width-(2*(width/5)),height-(height/3));   //Line3
  line(width/5,height/5,width-(3*(width/5)),height-(height/3));   //Line4
 
  
  // line in mouvement
  //line(10,10,mouseX, mouseY); PROCESSING EXAMPLE
  line(width/5,height-(height/3),mouseX, mouseY);
  
  //intersected = intersect(20, height/2, width-20, (height/2)-20, 10, 10, mouseX, mouseY);  PROCESSING EXAMPLE
  intersected = intersect(width/5,height/5,width,height-(height/3), width/5,height-(height/3),mouseX, mouseY);
  intersected = intersect(width/5,height/5,width-(width/5),height-(height/3), width/5,height-(height/3),mouseX, mouseY);
  //  intersection point
  noStroke();
  if (intersected == DO_INTERSECT) ellipse(x, y, 5, 5);

}


int intersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4){

  float a1, a2, b1, b2, c1, c2;
  float r1, r2 , r3, r4;
  float denom, offset, num;

  // Compute a1, b1, c1, where line joining points 1 and 2
  // is "a1 x + b1 y + c1 = 0".
  a1 = y2 - y1;
  b1 = x1 - x2;
  c1 = (x2 * y1) - (x1 * y2);

  // Compute r3 and r4.
  r3 = ((a1 * x3) + (b1 * y3) + c1);
  r4 = ((a1 * x4) + (b1 * y4) + c1);

  // Check signs of r3 and r4. If both point 3 and point 4 lie on
  // same side of line 1, the line segments do not intersect.
  if ((r3 != 0) && (r4 != 0) && same_sign(r3, r4)){
    return DONT_INTERSECT;
  }

  // Compute a2, b2, c2
  a2 = y4 - y3;
  b2 = x3 - x4;
  c2 = (x4 * y3) - (x3 * y4);

  // Compute r1 and r2
  r1 = (a2 * x1) + (b2 * y1) + c2;
  r2 = (a2 * x2) + (b2 * y2) + c2;

  // Check signs of r1 and r2. If both point 1 and point 2 lie
  // on same side of second line segment, the line segments do
  // not intersect.
  if ((r1 != 0) && (r2 != 0) && (same_sign(r1, r2))){
    return DONT_INTERSECT;
  }

  //Line segments intersect: compute intersection point.
  denom = (a1 * b2) - (a2 * b1);

  if (denom == 0) {
    return COLLINEAR;
  }

  if (denom < 0){ 
    offset = -denom / 2; 
  } 
  else {
    offset = denom / 2 ;
  }

  // The denom/2 is to get rounding instead of truncating. It
  // is added or subtracted to the numerator, depending upon the
  // sign of the numerator.
  num = (b1 * c2) - (b2 * c1);
  if (num < 0){
    x = (num - offset) / denom;
  } 
  else {
    x = (num + offset) / denom;
  }

  num = (a2 * c1) - (a1 * c2);
  if (num < 0){
    y = ( num - offset) / denom;
  } 
  else {
    y = (num + offset) / denom;
  }

  // lines_intersect
  return DO_INTERSECT;
}


boolean same_sign(float a, float b){

  return (( a * b) >= 0);
}


Replies(16)

It would be easier to have a method that returns either the intersection point (as a PVector) or null.

How about this?

Code Example
Copy code
  1. PVector[] lineCoordinates = new PVector[5];
  2. PVector mStart, mEnd;
  3.  
  4. void setup() {
  5.   size(600, 200);
  6.   lineCoordinates[0] = new PVector(width/5, height/5);                      // start
  7.   lineCoordinates[1] = new PVector(width, height-(height/3));               // line 1
  8.   lineCoordinates[2] = new PVector(width-(width/5), height-(height/3));     // line 2
  9.   lineCoordinates[3] = new PVector(width-(2*(width/5)), height-(height/3)); // line 3
  10.   lineCoordinates[4] = new PVector(width-(3*(width/5)), height-(height/3)); // line 4
  11.   mStart = new PVector(width/5, height-(height/3));
  12.   mEnd = new PVector();
  13.   fill(0);
  14. }
  15.  
  16. void draw() {
  17.   background(255);
  18.  
  19.   line(0, height-(height/3), width, height-(height/3));
  20.  
  21.   mEnd.set(mouseX, mouseY, 0);
  22.   line(mStart, mEnd);
  23.  
  24.   for (int i=1; i<lineCoordinates.length; i++) {
  25.     line(lineCoordinates[0], lineCoordinates[i]);
  26.     PVector is = lineIntersection(lineCoordinates[0], lineCoordinates[i], mStart, mEnd);
  27.     if (is!=null) { ellipse(is.x, is.y, 5, 5); }
  28.   }
  29. }
  30.  
  31. void line(PVector s, PVector e) {
  32.   line(s.x, s.y, e.x, e.y);
  33. }
  34.  
  35. PVector lineIntersection(PVector p1, PVector p2, PVector p3, PVector p4) {
  36.   PVector b = PVector.sub(p2, p1);
  37.   PVector d = PVector.sub(p4, p3);
  38.  
  39.   float b_dot_d_perp = b.x * d.y - b.y * d.x;
  40.   if (b_dot_d_perp == 0) { return null; }
  41.  
  42.   PVector c = PVector.sub(p3, p1);
  43.   float t = (c.x * d.y - c.y * d.x) / b_dot_d_perp;
  44.   if (t < 0 || t > 1) { return null; }
  45.   float u = (c.x * b.y - c.y * b.x) / b_dot_d_perp;
  46.   if (u < 0 || u > 1) { return null; }
  47.  
  48.   return new PVector(p1.x+t*b.x, p1.y+t*b.y);
  49. }
Thanks so much! That seems really good but I found it too difficult to understand! I'm just a beginner and I need extra help!
also I ran the code and I found an error,in this line:

  return new PVector(p1.x+t*b.x, p1.y+t*b.y);

Found one too many { characters without a } to match it. which I really don't know what it means!!!! 




maybe you forget the last }   ?

The last error means something went wrong when you copy-pasted the code, because apparantly you missed the last } on line 49. Then you will get this error. Use the "Copy code" button on the top-right of the code and copy everything and it will work ok.

If you have any questions about the code, feel free to ask. I can probably answer them, except when it comes to the math stuff inside the lineIntersection() method, which ain't my strong point. Whatever works!
Yes!!!
 sorry! I am really an amateur!!! 
 I love you guys!!!

thanks! 
Now I'm reading the references to learn about PVector and the rest of the code! I should learn it in order to explain it in my presentation!  

Thanks again!
Oh Nooooo!

this script doesn't run in processing.js !
I need the javascript code.

any idea?

" this script doesn't run in processing.js !"
Why? Isn't PVector implemented in JS?
well , That is my problem!!!!

maybe the array or other commands. I have no clue! there is no error. it just doesn't show anything!

I think function overloading is not supported in JS. Try renaming the custom line() method to something else like drawLine(). Change lines 22, 25 and 31 to change the name. See if it works then.
No! it doesn't work!

To me everything look fine! I checked all the commands in the reference page in the website! everything was there. still not sure about the array(). the example given in the website is a bit different but it has the same function (  http://processingjs.org/reference/PVector_array_/)

PVector v = new PVector(10.0, 20.0, 30.0);
float[] f = v.array();
println(f[0]);  // Prints "10.0"
println(f[1]);  // Prints "20.0"
println(f[2]);  // Prints "30.0"
I think the problem is in PVector section, because it doesn't draw a single line!
I updated the code and I add some texts and simple ellipse to it, which there are totally independent to the vectors. and my browser only shows that bit!
My code doesn't use array(). And I seriously doubt you followed my suggestions correctly. Because when I try the old code in online JS it doesn't work, but when I make the suggested changes it DOES work. Let me just post the adapted code for you. Then try that.

Adapted Code
Copy code
  1. PVector[] lineCoordinates = new PVector[5];
  2. PVector mStart, mEnd;
  3.  
  4. void setup() {
  5.   size(600, 200);
  6.   lineCoordinates[0] = new PVector(width/5, height/5);                      // start
  7.   lineCoordinates[1] = new PVector(width, height-(height/3));               // line 1
  8.   lineCoordinates[2] = new PVector(width-(width/5), height-(height/3));     // line 2
  9.   lineCoordinates[3] = new PVector(width-(2*(width/5)), height-(height/3)); // line 3
  10.   lineCoordinates[4] = new PVector(width-(3*(width/5)), height-(height/3)); // line 4
  11.   mStart = new PVector(width/5, height-(height/3));
  12.   mEnd = new PVector();
  13.   fill(0);
  14. }
  15.  
  16. void draw() {
  17.   background(255);
  18.  
  19.   line(0, height-(height/3), width, height-(height/3));
  20.  
  21.   mEnd.set(mouseX, mouseY, 0);
  22.   drawLine(mStart, mEnd);
  23.  
  24.   for (int i=1; i<lineCoordinates.length; i++) {
  25.     drawLine(lineCoordinates[0], lineCoordinates[i]);
  26.     PVector is = lineIntersection(lineCoordinates[0], lineCoordinates[i], mStart, mEnd);
  27.     if (is!=null) { ellipse(is.x, is.y, 5, 5); }
  28.   }
  29. }
  30.  
  31. void drawLine(PVector s, PVector e) {
  32.   line(s.x, s.y, e.x, e.y);
  33. }
  34.  
  35. PVector lineIntersection(PVector p1, PVector p2, PVector p3, PVector p4) {
  36.   PVector b = PVector.sub(p2, p1);
  37.   PVector d = PVector.sub(p4, p3);
  38.  
  39.   float b_dot_d_perp = b.x * d.y - b.y * d.x;
  40.   if (b_dot_d_perp == 0) { return null; }
  41.  
  42.   PVector c = PVector.sub(p3, p1);
  43.   float t = (c.x * d.y - c.y * d.x) / b_dot_d_perp;
  44.   if (t < 0 || t > 1) { return null; }
  45.   float u = (c.x * b.y - c.y * b.x) / b_dot_d_perp;
  46.   if (u < 0 || u > 1) { return null; }
  47.  
  48.   return new PVector(p1.x+t*b.x, p1.y+t*b.y);
  49. }
Yes you are right! I'm sorry, I may misunderstood .
It looks perfect. 

I'm a bit curious  what wat the reason for that? you said " function overloading is not supported in JS," but what does that mean?
sorry I'm asking too much, but I really want to learn!
Function or method overloading is when you have more than 1 with same name inside a class.
But they have different types and/or number of parameters.

Java language is smart enough to know which one to call
by analyzing which parameters you have passed to call 1 of them!
Thanks So much.

I think in my case it was the line() function.