Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Line in box collision  (Read 13512 times)

0 Members and 1 Guest are viewing this topic.

Gregory

  • Newbie
  • *
  • Posts: 41
    • View Profile
Line in box collision
« on: November 06, 2010, 07:17:18 pm »
Hey guys!? how can i check if have a intersect/collision of a line in a rectangle?




i made this code, but is very slow for a lot of lines and rectangles:

Code: [Select]
bool line_collision(int x1, int y1,int x2,int y2,const gameobj& other,int precise) {
    int x,y,angle,dist;
    angle = point_direction(x1,y1,x2,y2);
    dist = point_distance(x1,y1,x2,y2);
    for(int i = 0 ; i < dist ; i+=precise) {
        x = (x1-cos(angle*(DEG))*i);
        y = (y1-sin(angle*(DEG))*i);
        if (x >= other.x + other.rect.Left and x <= other.x + other.rect.Right) {
            if (y >= other.y + other.rect.Top and y <= other.y + other.rect.Bottom) {
                return 1;
            }
        }
    }
    return 0;
}


i think that have others ways to do this, can you help me?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #1 on: November 06, 2010, 11:20:40 pm »
Hi!

Your code is O(n) where n~(line length / precise) so yes it's slow. Everything is about this loop. You can do without it and have a function=O(m) where m is the number of side of your box :

Let l=ax+b and m(i)=c(i)x+d with x,a,b,c(i) and d in R. Hence l and m(i) are in R. l is the equation for the line and m(i) is the equation of the i-th side of the box.

- for each side of the box do
-- find the intersection between the i-th side of the box and the line by solving the equation system l=m(i)
-- check if the solution of the system is "out" of the side or not.

BTW use true/false instead of 1/0 even if it means the same for the computer : it is much more readable for human like us. ;-)
SFML / OS X developer

Gregory

  • Newbie
  • *
  • Posts: 41
    • View Profile
Line in box collision
« Reply #2 on: November 07, 2010, 04:32:46 am »
sorry, but i didn't understand what you spoke. can you give an example?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #3 on: November 07, 2010, 11:19:17 am »
Well, it requires some maths so tell my what your maths level (ie. age, school, country, ...) is so I can turn the explanation around to be understandable.  :wink:
SFML / OS X developer

Gregory

  • Newbie
  • *
  • Posts: 41
    • View Profile
Line in box collision
« Reply #4 on: November 07, 2010, 02:42:15 pm »
i have 15 years, i get a code in internet that works, but i wanted make my code

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #5 on: November 07, 2010, 05:28:31 pm »
Damn! 15 that's so young!  :P


So, the first thing you need to know is what is a line. Check that out for the basis : [1]

Here we're going to use only to thing :
a) a line f is representable mathematically by y=a*x+b where a is the slope [2] of the line and b is the y-intercept of the line [3].
b) a line can be defined by two points O(o1, o2) and P(p1, p2).

In fact our line f is a linear equation [4].

From the point O and P we can find our a and b with these formulas :
a = (o2 - p2) / (o1 - p1)
b = o2 - a * o1 which is also b = p2 - a * p1

Now you know how to create any line. :wink:

The next step is to take two lines, let's say f and g which are y=a*x + b and y=c*x + d, respectively, and find their intersection [5].

To do that we have to solve the linear system given by f and g. It may sound very complicated but it's quite easy in fact.

This idea is very basic : we want to find the couple (x,y) such that y = a*x + b = c*x + d. (Remember we know a, b, c and d.) Hence a*x - c*x = d - b.

a*x - c*x can be written as x * (a - c) thus if we divide both side of a*x - c*x = d - b by (a - c) we have x = (d - b) / (a - c).

Now we know the value of x but we still don't know what is y. To know it we go back to y = a*x + b and «simply» compute y.

Now you know where the two line f and g intersect. But in our square we don't have line but segments [6]. Thus we have to check if our intersection (x,y) is «in» our segment or «out». This check is very easy :

Let's say our two segments are delimited by two points M(m1, m2) N(n1, n2) and I(i1, i2), J(j1, j2), respectively. Then you only check if x is between m1 and n1 and between i1 and j1. Or you check y. Checking x AND y is useless because if x is «in» then y is also «in» and vice versa.

If you have some trouble with anything try first to make some sketching then if you still don't understand ask me. :wink:

Now to check if your line go through your box you have to check each side.

Have FUN !

(NB : most part of wiki articles are out of our scope. Don't be afraid of what you're going to read there. Everything you'll need is explained here.)

[1] http://en.wikipedia.org/wiki/Line_(geometry)
[2] http://en.wikipedia.org/wiki/Slope
[3] http://en.wikipedia.org/wiki/Y-intercept
[4] http://en.wikipedia.org/wiki/Linear_equation
[5] http://en.wikipedia.org/wiki/Line_intersection
[6] http://en.wikipedia.org/wiki/Line_segment

PS : just wondering : are you German ?
SFML / OS X developer

NoIdea

  • Full Member
  • ***
  • Posts: 149
    • View Profile
Line in box collision
« Reply #6 on: November 07, 2010, 05:40:53 pm »
Isnt a line equation more like ax + by = c ?
The easiest is to transform the line in the rectangle's coordinate system. Then, your rectangle is an AABB box. Easy isn't it ?

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
Line in box collision
« Reply #7 on: November 07, 2010, 06:03:39 pm »
Quote from: "NoIdea"
Isnt a line equation more like ax + by = c ?
The easiest is to transform the line in the rectangle's coordinate system. Then, your rectangle is an AABB box. Easy isn't it ?


You are not helping.... This is the same,you just have written it differently, a line has infinite different equation. But you know that, do you?

What's the point? Don't you see he just want to make his own code, he just need to understand how that's work.

Why do you every need to show us how much you know ?

NoIdea

  • Full Member
  • ***
  • Posts: 149
    • View Profile
Line in box collision
« Reply #8 on: November 07, 2010, 08:07:44 pm »
Because ax+c doesn't deal with vertical lines !
Furthermore, once the rectangle is an AABB box, it's even simpler !
Equation of one of the sides becomes x=bottom or top or y=left or right

Gregory

  • Newbie
  • *
  • Posts: 41
    • View Profile
Line in box collision
« Reply #9 on: November 07, 2010, 10:28:33 pm »
oww, thank you, i will try! and not, i'm brazillian

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #10 on: November 07, 2010, 10:33:27 pm »
Quote
Because ax+c doesn't deal with vertical lines !
So does ax + by = c . As they mean the same, you can do this :

ax + by = c -> by = c - ax = a'x + c -> y = (a'x + c) / b = a''x + c' with b in R* = R\{0} (all value but 0).

Quote
Equation of one of the sides becomes x=bottom or top or y=left or right
What do you mean ?

ANYWAY :

And what if you don't have a box with four side but three, seven , ... ?

PS : next time take the same amount of time I took to write all of this down.
SFML / OS X developer

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #11 on: November 07, 2010, 10:34:01 pm »
Quote from: "Gregory"
oww, thank you, i will try! and not, i'm brazillian
Damn! I lost ! Hahaha
SFML / OS X developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Line in box collision
« Reply #12 on: November 07, 2010, 10:43:38 pm »
Quote from: "Hiura"
Quote from: "Gregory"
oww, thank you, i will try! and not, i'm brazillian
Damn! I lost ! Hahaha


Auuw I'll go with your way anyway XD
Cause that's the equation I remember from school which we called: "Straight Lines Equation"(Swe: Räta linjens ekvation)

Though never used it to detect if it intersects with a side of a polygon.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

NoIdea

  • Full Member
  • ***
  • Posts: 149
    • View Profile
Line in box collision
« Reply #13 on: November 07, 2010, 10:49:01 pm »
Ax + by = c means that when b = 0, the line is vertical.
As for the length of my messages, i'm writting with my phone which isn't so convenient
A AABB box means axis aligned box and thus has very convenient line equations.

If i remember well, ax + by = c is the cartesian equation. The ax + b = c is in french called "équation réduite"

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Line in box collision
« Reply #14 on: November 07, 2010, 11:25:07 pm »
Don't mix up «time» and «length».

So if a AABB box has no rotation what's the point ? It's too inflexible. Like the number of side. Even if it's «simpler» the gain is not interesting.

One more question : how can you find ax+by=c with two points ? Hard, isn't it ?   :roll:
SFML / OS X developer