AS: Line to Line Collision
by Glaiel Gamer
AS: MAIN
----------------INTRODUCTION--------------
Collision detection, we all need to use it in a game, right? Our first impression would be to instantly use versions of hitTest, shapeflag, and the Pythagorean Theorem. Well, I was fooling around today, and I was REALLY bored in Algebra 2 cause It was all review so I was thinking. I doodled equations. And after school, I came up with this neat line to line collision detection function, which could essentially be used for polygons also.
STUFF TO KNOW:
y = mx+b
y-y1 = m(x-x1)
How to use substitution to solve systems of equations.
------------THE CODE, BROKEN DOWN AND COMMENTED---------
createEmptyMovieClip("d", 1);
createEmptyMovieClip("s1", 2);
s1.lineStyle(2, 0xFF0000, 95);
s1.moveTo(-5, -5);
s1.beginFill(0xFF0000, 20);
s1.lineTo(-5, 5);
s1.lineTo(5, 5);
s1.lineTo(5, -5);
s1.lineTo(-5, -5);
s1.endFill();
col = "0xFF0000";
duplicateMovieClip(s1, "s2", 3);
duplicateMovieClip(s1, "s3", 4);
duplicateMovieClip(s1, "s4", 5);
duplicateMovieClip(s1, "s5", 6);
s1._x = 100;
s1._y = 100;
s2._x = 200;
s2._y = 100;
s3._x = 300;
s3._y = 300;
s4._x = 400;
s4._y = 300;
// This first block of code is a little bit of API, just to draw the squares and create the MC where we print the line in
s1.onPress = s2.onPress=s3.onPress=s4.onPress=function () {
startDrag(this);
};
s1.onMouseUp = s2.onMouseUp=s3.onMouseUp=s4.onMouseUp=fun
ction () {
stopDrag();
};
//Just a simple dragging code
_root.onEnterFrame = function() {
d.clear();
d.lineStyle(3, col, 100);
d.moveTo(s1._x, s1._y);
d.lineTo(s2._x, s2._y);
d.moveTo(s3._x, s3._y);
d.lineTo(s4._x, s4._y);
// Draws the line between the points
line1 = new Object();
//here's where the good stuff starts. My function was written to input 2 line objects (my custom line objects) so we make an object for line 1
line1.x1 = s1._x;
line1.y1 = s1._y;
line1.x2 = s2._x;
line1.y2 = s2._y;
// these are the 2 endpoints points of the line, pretty self explanitory
line1.m = (line1.y1-line1.y2)/(line1.x1-line1.x2);
// m=slope. Slope will come in handy. Just a flash translation of the slope forumla
if (line1.x1-line1.x2 == 0) {
line1.m = 99999999;
}
// We don't want a vertical slope, so if the denominator is 0 we make slope a really high number
line1.b = (-1)*(line1.m*line1.x1-line1.y1);
// The y-intercept. I used y-y1 = m(x-x1) and translated it down to solve for b. I got it into y=mx+b format, and b turned out to be mx1-y1. Then I multiplied by -1 because flash has an inverted y axis.
line2 = new Object();
line2.x1 = s3._x;
line2.y1 = s3._y;
line2.x2 = s4._x;
line2.y2 = s4._y;
line2.m = (line2.y1-line2.y2)/(line2.x1-line2.x2);
if (line2.x1-line2.x2 == 0) {
line2.m = 99999999;
}
line2.b = (-1)*(line2.m*line2.x1-line2.y1);
// We do the same for our other line
poi = new Object();
// Poi stands for point of intersection.
poi = systemEQ(line1, line2);
// systemEQ is the function I wrote that solves systems of equations, or in other words, finds the point where the 2 lines intersect. poi now has 2 values, xi (x intersect) and yi (y intersect)
if (linetoline(line1, line2, poi)) {
col = "0xFF0000";
} else {
col = "0x000000";
}
//linetoline will be explained in detail later, but it is in essence a version of a line hittest that needs 2 lines and the point of intersection.
s5._x = poi.xi;
s5._y = poi.yi;
// Places a square on poi
};
function systemEQ(line1, line2) {
var rf = new Object();
rf.xi = (line1.b-line2.b)/(line2.m-line1.m);
rf.yi = line1.m*rf.xi+line1.b;
return (rf);
// I'm gonna explain this in one large chunk. y=mx+b for line 1 and y=mx+b for line 2. Using the substitution method, m1x+b1 = m2x+b2. Now I isolated x (x=(b1-b2)/(m2-m1)), and since all the other values are given in the line object, x is now a number. I plug it into y=mx+b to find the y intersect coordinate. Now the function returns the point of intersection. This was the hardest part, writing a function to parse algebraic problems.
}
function linetoline(line1, line2, poi) {
if(line1.x1 == line1.x2){
line1.x1 += .00001
}
if(line1.y1 == line1.y2){
line1.y1 += .00001
}
//I found out that vertical lines don't parse well here.
if ((((poi.xi>line1.x1 && poi.xi<line1.x2) || (poi.xi<line1.x1 && poi.xi>line1.x2)) && ((poi.xi>line2.x1 && poi.xi<line2.x2) || (poi.xi<line2.x1 && poi.xi>line2.x2))) || (((poi.yi>line1.y1 && poi.yi<line1.y2) || (poi.yi<line1.y1 && poi.yi>line1.y2)) && ((poi.yi>line2.y1 && poi.yi<line2.y2) || (poi.yi<line2.y1 && poi.yi>line2.y2)))) {
return (true);
} else {
return (false);
}
//Here's the bulk of this function. NG will probably break the if statement into like 10 lines, it's a long line of code. Basically, it tests if the point of intersection is between the endpoints of the line. It really is a simple line of code, the reason why it is so long is because it is so repetitive.
}
-----------CONCLUSION------------
USEFULNESS?
Of course it's useful. It could be used to provide a quick method of gunfire in a game like hollow point if you can do line-line rather than a thick line and shapeflag. There's many other uses too, but that's for you to figure out.
LINKS:
Example: http://media.putfile.com/line-line
AS Collision Threads:
http://www.newground../topic.php?id=293660
http://www.newground../topic.php?id=296755
And A really helpful thread:
http://www.newground../topic.php?id=354500
~ Glaiel Gamer