You are not logged in.

- Topics: Active | Unanswered

Pages: **1**

**bossk171****Member**- Registered: 2007-07-16
- Posts: 303

I'm working on a Flash game, and I can't come up with a simple algorithm to test if to line segments intersect.

I know I can do it, but as I go along things get more and more complicated (which means: more room for bugs) and I keep thinking there's got to be and easier way of doing it.

So I googled it, and came across this essay on a "sweep line algorithm" but that seems even more complicated then the way I was doing it.

Is there an easier way to do it? I know Actionscript isn't a very popular programming language (unless you're into game design) so if someone can just give me the theory, or maybe an example in C++ (that's the only other language I know) I would really appreciate it.

I really feel like I'm missing something here, this should be real easy, and yet...

*Last edited by bossk171 (2007-11-02 14:45:46)*

There are 10 types of people in the world, those who understand binary, those who don't, and those who can use induction.

Offline

**luca-deltodesco****Member**- Registered: 2006-05-05
- Posts: 1,470

define your two line segments as A[sub]0[/sub] to A[sub]1[/sub] and B[sub]0[/sub] to B[sub]1[/sub] so that you can imagine them as a couple of rays

so that you have removing the 0 index for easier reading

then you have the condition:

this isn't nice to work with, so lets look at it a different way:

as you move along the B ray, and take a vector from A[0] to B[s] the point at which the two rays intersect, is when this vector is parallel to V, or that its perpendicular vector is perpendicular to V: the reason for this is that to find if two vectors are parallel, you have to dot them, and check that the value of the dot product is plus-minus the product of the two magnitudes, whereas checking for perpendicular vectors, no matter what their magnitudes are, the dot product is 0 if they are perpendicular, so you don't need to work out their lengths

if we define a unary operator

which is just the same as having the vector transformed by a 90 degree rotation matrix, so all rules apply the same as multiplying with a matrixSo we have:

similarly working for t you get

note that the denominators are the same, so you can pre-compute the inverse of the denominator for faster execution time:

the only time this fails is if Q and V are parallel, in which case the denominator is 0, but in this case it is either that they never intersect (even going past limits of line segment) or that they are the same line segment

then you would do it like this:

```
calculate inverse of denominator
calculate s
if (s < 0 || s > 1) return false
calculate t
return (t >= 0 && t<=1)
```

so with this you can find if they intersect, and if they do intersect, use either the value for s or t to calculate the exact intersection point

*Last edited by luca-deltodesco (2007-11-03 00:19:23)*

The Beginning Of All Things To End.

The End Of All Things To Come.

Offline

**bossk171****Member**- Registered: 2007-07-16
- Posts: 303

I really hate to say this but... what?

Am I missing something here? That still seems really confusing.

There are 10 types of people in the world, those who understand binary, those who don't, and those who can use induction.

Offline

**mikau****Member**- Registered: 2005-08-22
- Posts: 1,504

luca is creating parametrically defined lines. suppose you have the line from (a,b) to (c,d). This consists of all points of the form (x,y) = (a, b) + t[(c,d) - (a,b)] for any t you pick, this gives you the point you reach if you start at (a, b) and walk t times the distance from (a,b) to (c,d), walking directly towards (c,d). Note, if you chose t= 1/2, you have (a,b) + 1/2(c,d) - 1/2(a,b) = 1/2[(a,b) + (c,d)] which is the midpoint between the two, which is what we'd expect. Further, if we walk 1 times the distance from (a,b) to (c,d) we should end up at (c,d), and indeed (a,b) + 1[(c,d) - (a,b)] = (a,b) + 1(c,d) - 1(a,b) = (c,d).

The point is, if you pick a t greater than 1 or less than zero, you are no longer finding a point that lies partway between the two. What luca is doing is finding two parametrically defined lines that define the two given line segments. In one line, the parameter is t, in the other it is s, he is then finding for what values of t and s these two lines intersect. If either of them are greater than 1 or less than zero, then you have to 'walk outside' the two line segments in order to reach the intersection point. Why? if t > 1, then we are talking about a point that lies further than the whole distance from (a,b) to (c,d), which means they do not intersect within those boundaries. Further, if t < 0, then t is negative, which means we are starting at (a,b) and walking backwards, away from (c,d) which certainly means the intersection point does not lie somewhere between (a,b) and (c,d).

In otherwords, he is defining two infinite lines, finding where they intersect, and then seeing if the lines fall within the boundaries of the line segments.

Does that make sense? Do you understand the vector notation luca is using?

*Last edited by mikau (2007-11-04 05:34:58)*

A logarithm is just a misspelled algorithm.

Offline

**luca-deltodesco****Member**- Registered: 2006-05-05
- Posts: 1,470

here is a flash (i have CS3 so i could only export at minimum to flash 8) http://ngup.net/uploads/217476_mif.fla

and heres the corresponding swf for it: http://ngup.net/uploads/mif.swf (drag points)

The Beginning Of All Things To End.

The End Of All Things To Come.

Offline

**bossk171****Member**- Registered: 2007-07-16
- Posts: 303

I think it's the vector notation I'm getting hung up on. The explanation: "In otherwords, he is defining two infinite lines, finding where they intersect, and then seeing if the lines fall within the boundaries of the line segments." really helps though.

Thanks for really breaking it down for me guys, and especially thanks for posting that fla.

There are 10 types of people in the world, those who understand binary, those who don't, and those who can use induction.

Offline

Pages: **1**