Below I have a Processing sketch that includes the function intersection which compares two lines. Copy/paste the text below into a processing sketch window and go. Everything else outside the function is just to facilitate the demo sketch. Moving the mouse pointer around moves the other line, whereas the other line moves randomly.
It's based on a very old program so it might not be up to scratch. My previous work also returned the intersection coordinate (what I was really after), so this is clearly a simpler case.
There's always the problem that two parallel lines, even if they overlap visibly, coordinate-wise they may not intersect mathematically. For example, lines 0,0-100,0 and 50,0-150,0 do not intersect. The program below does not solve this case. I've supposed that making multiple intersection tests with suitably "jiggled" coordinates might fix this problem for some practical purposes.
Not intersecting! |
Intersecting! |
float [] xp=new float[8];
float [] yp=new float[8];
float [] xv=new float[8];
float [] yv=new float[8];
boolean intersection(float X1,float Y1,float X2,float Y2,float X3,float Y3,float X4,float Y4)
{
//Tests intersection between lines x1,y1-x2,y2 and x3,y3-x4,y4
//Not sure where the original formulas are from.
//The function has the practical problem that parallel lines do not intersect.
//This may be circumvented by "jiggling" the line coordinates just a bit and making two intersection tests, not implemented here
//My original function returned the intersection coordinate, this is a simplification
float ua,ub,denom,numer;
//not sure if the following are needed really
if(X3>X2&&X4>X2&&X3>X1&&X4>X1){return false;}
if(X3<X2&&X4<X2&&X3<X1&&X4<X1){return false;}
if(Y3>Y2&&Y4>Y2&&Y3>Y1&&Y4>Y1){return false;}
if(Y3<Y2&&Y4<Y2&&Y3<Y1&&Y4<Y1){return false;}
// the proper calculations
numer=((X4-X3)*(Y1-Y3)-(Y4-Y3)*(X1-X3));
denom=((Y4-Y3)*(X2-X1)-(X4-X3)*(Y2-Y1));
if(denom==0){return false;}
ua=(numer/denom);
numer=((X2-X1)*(Y1-Y3)-(Y2-Y1)*(X1-X3));
ub=(numer/denom);
if(ua==0&&ub==0){return true;}
if(ub>0&&ub<=1&&ua>0&&ua<=1){return true;}
return false;
}
void draw_lines(float xa1,float ya1,float xa2,float ya2,float xb1,float yb1,float xb2,float yb2)
{
if(intersection(xa1,ya1,xa2,ya2,xb1,yb1,xb2,yb2)==true){
stroke(255,0,0);line(xa1,ya1,xa2,ya2);line(xb1,yb1,xb2,yb2);
}else
{
stroke(0,255,0);line(xa1,ya1,xa2,ya2);line(xb1,yb1,xb2,yb2);
}
}
void setup()
{
size(512,512);
strokeWeight(2);
xp[0]=16;yp[0]=16;xp[1]=64;yp[1]=64;
xv[0]=2;yv[0]=1;
xv[1]=-3;yv[1]=-1;
xp[2]=width/2;yp[2]=height/2;xp[3]=width/2;yp[3]=height/2;
}
void mousePressed()
{
xp[2]=mouseX;yp[2]=mouseY;
}
void draw()
{
background(0,0,128);
draw_lines(xp[0],yp[0],xp[1],yp[1],xp[2],yp[2],xp[3],yp[3]);
for(int i=0;i<=7;i++){
xp[i]=xp[i]+xv[i];
yp[i]=yp[i]+yv[i];
if(xp[i]>=width){xv[i]=-(1+random(2));}
if(xp[i]<=0){xv[i]=1+random(2);}
if(yp[i]>=height){yv[i]=-(1+random(2));}
if(yp[i]<=0){yv[i]=1+random(2);}
}
xp[3]=mouseX;
yp[3]=mouseY;
}
No comments:
Post a Comment