my ball line collision solution
in
Share your Work
•
3 years ago
I've finally got a ball line collision solution I like. I'm always in a position of wanting to know if a ball is touching a line and/or if a ball has crossed a line. Props to Jeanine Meyer for some of the math help.
int xStart = 50;
int yStart = 50;
int xEnd = 300;
int yEnd = 300;
int xBall = 20;
int yBall = 20;
int balldiameter = 20;
int oldxball, oldyball;
void setup() {
size(400, 400);
smooth();
}
void draw() {
background(200);
oldxball = xBall;
oldyball = yBall;
xBall = mouseX;
yBall = mouseY;
if (crossOverLine(xBall, yBall, oldxball, oldyball, xStart, yStart, xEnd, yEnd)) {
println ("crossed Over Line");
fill(255, 0, 0);
}
else if (touchingLine(xStart,yStart,xEnd,yEnd,xBall,yBall,balldiameter/2)) {
println ("touching Line");
fill(255, 255, 0);
}
else {
fill (255, 255, 255);
}
line (xStart, yStart, xEnd, yEnd);
ellipse (xBall, yBall, balldiameter, balldiameter);
}
boolean crossOverLine (float px, float py,float qx,float qy,float ax,float ay,float bx,float by) {
float s,t, w1,w2,w3,w4,w5,w6;
w1=ax*(qy-py);
w2 = (bx-ax)*(qy-py);
w3 = px*(qy-py);
w4= (qx-px)*ay;
w5= (by-ay)*(qx-px);
w6= py*(qx-px);
if (w2==w5) {
return false;
}
s = (w3-w1+w4-w6)/(w2-w5);
if (s<0) {
return false;
}
if (s>1) {
return false;
}
if (qx==px) {
return false;
}
t = (ax+s*(bx-ax)-px)/(qx-px);
if (t<0) {
return false;
}
if (t>1) {
return false;
}
return true;
}
boolean touchingLine (float px, float py, float qx, float qy, float cx, float cy, int rad ) {
float dx, dy, t, rt;
dx = qx-px;
dy = qy-py;
t =0.0-((px-cx)*dx+(py-cy)*dy)/((dx*dx)+(dy*dy));
if (t<0.0) {
t=0.0;
}
else if (t>1.0) {
t = 1.0;
}
//check if distance at this t is less than radius, actually compare squares
dx = (px+t*(qx-px))-cx;
dy = (py +t*(qy-py))-cy;
rt = (dx*dx) +(dy*dy);
if (rt<(rad*rad)) {
return true;
}
else {
return false;
}
}
int xStart = 50;
int yStart = 50;
int xEnd = 300;
int yEnd = 300;
int xBall = 20;
int yBall = 20;
int balldiameter = 20;
int oldxball, oldyball;
void setup() {
size(400, 400);
smooth();
}
void draw() {
background(200);
oldxball = xBall;
oldyball = yBall;
xBall = mouseX;
yBall = mouseY;
if (crossOverLine(xBall, yBall, oldxball, oldyball, xStart, yStart, xEnd, yEnd)) {
println ("crossed Over Line");
fill(255, 0, 0);
}
else if (touchingLine(xStart,yStart,xEnd,yEnd,xBall,yBall,balldiameter/2)) {
println ("touching Line");
fill(255, 255, 0);
}
else {
fill (255, 255, 255);
}
line (xStart, yStart, xEnd, yEnd);
ellipse (xBall, yBall, balldiameter, balldiameter);
}
boolean crossOverLine (float px, float py,float qx,float qy,float ax,float ay,float bx,float by) {
float s,t, w1,w2,w3,w4,w5,w6;
w1=ax*(qy-py);
w2 = (bx-ax)*(qy-py);
w3 = px*(qy-py);
w4= (qx-px)*ay;
w5= (by-ay)*(qx-px);
w6= py*(qx-px);
if (w2==w5) {
return false;
}
s = (w3-w1+w4-w6)/(w2-w5);
if (s<0) {
return false;
}
if (s>1) {
return false;
}
if (qx==px) {
return false;
}
t = (ax+s*(bx-ax)-px)/(qx-px);
if (t<0) {
return false;
}
if (t>1) {
return false;
}
return true;
}
boolean touchingLine (float px, float py, float qx, float qy, float cx, float cy, int rad ) {
float dx, dy, t, rt;
dx = qx-px;
dy = qy-py;
t =0.0-((px-cx)*dx+(py-cy)*dy)/((dx*dx)+(dy*dy));
if (t<0.0) {
t=0.0;
}
else if (t>1.0) {
t = 1.0;
}
//check if distance at this t is less than radius, actually compare squares
dx = (px+t*(qx-px))-cx;
dy = (py +t*(qy-py))-cy;
rt = (dx*dx) +(dy*dy);
if (rt<(rad*rad)) {
return true;
}
else {
return false;
}
}
2