Results 1 to 39 of 39

Thread: [RESOLVED] Intersecting Lines

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Resolved [RESOLVED] Intersecting Lines

    I have to admit that I haven't even thought about this problem, so it may be SERIOUSLY easy, but I'm designing something different, and know this place is a source for good suggestions, so here it is:

    I have two objects in a database. These objects could be defined down to two points, and I almost certainly will do it that way, though the objects are 3D. Therefore, there is a line segment defined by the points (X1,Y1) - (X2,Y2).

    I will also have another table of line segments. Without any thought, I can query the database to find that set of line segments that are near the target line segment, but I'm looking for a way to determine whether one of the line segments in the table intersect the target line segment.

    Here's the reason: One piece of a robot brain will be examining gaps in the map it is creating of the world. A gap is an unexplored area between two objects (which have been identified by other modules based on touch and ultrasonic echo location). One thing about echo location is that I only get single points from an object, so I can't tell without some kind of investigation whether two echoes are separate objects, or the same (there's MUCH more going into it than that, but I don't want to write a book here). Therefore, this module will figure out which gaps should be investigated to see whether or not they are real, or just blind spots. To do this, the robot will have to figure out whether or not it has traveled through the gaps that have been found. Thus, the points mentioned are the objects, and the line segment table will hold the past travels of the bot. Of course, gap detection is something the bot will be doing only when it doesn't have something more important to do, but it will go into building a more accurate world map.
    My usual boring signature: Nothing

  2. #2
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Hi Shaggy, I'm using the following Function to calculate intersections.
    Note that it will Return a Intersection of X=0 and Y=0 if no intersection is found! Furthermore the found Intersection be outside of the Start/End of a line! I'm using another routine to check for that.
    Code:
        Public Function Intersection(ByVal Line1Start As PointF, ByVal Line1End As PointF, ByVal Line2Start As PointF, ByVal Line2End As PointF) As PointF
            'Input Start and EnpPoint of Lines
            'Output the Intersection
            Dim DX1 As Single
            Dim DX2 As Single
            Dim DY1 As Single
            Dim DY2 As Single
            Dim M1 As Single
            Dim M2 As Single
            Dim B1 As Single
            Dim B2 As Single
            Dim SymPoint As PointF
            DX1 = Line1End.X - Line1Start.X
            DX2 = Line2End.X - Line2Start.X
            DY1 = Line1End.Y - Line1Start.Y
            DY2 = Line2End.Y - Line2Start.Y
            If Not Math.Abs(DX1) <= 0.001 Then
                M1 = DY1 / DX1
            End If
            If Not Math.Abs(DX2) <= 0.001 Then
                M2 = DY2 / DX2
            End If
            B1 = Line1Start.Y - M1 * Line1Start.X
            B2 = Line2Start.Y - M2 * Line2Start.X
            If Math.Abs(DX1) <= 0.001 Or Math.Abs(DX2) <= 0.001 Then
                'Special cases for North/South Lines
                If Math.Abs(DX1) <= 0.001 And DX2 <> 0 Then
                    'The Intersection has to be at Line1Start.X
                    'only the Y coordinate has to be calculated
                    Intersection.X = Line1Start.X
                    Intersection.Y = Line2Start.Y + M2 * (Line1Start.X - Line2Start.X)
                End If
                If Math.Abs(DX2) <= 0.001 And DX1 <> 0 Then
                    'The Intersection has to be at Line2Start.X
                    'only the Y coordinate has to be calculated
                    Intersection.X = Line2Start.X
                    Intersection.Y = Line1Start.Y + M2 * (Line2Start.X - Line1Start.X)
                End If
                If Math.Abs(DX1) <= 0.001 And Math.Abs(DX2) <= 0.001 Then
                    'both Lines run North/South
                    'An Intersection exists only if one of the Endpoints of one Line in within the Endpoints of the other Line!
                    If Line1Start.Y < Line1End.Y Then
                        If (Line2Start.Y >= Line1Start.Y And Line2Start.Y <= Line1End.Y) Then
                            Intersection.Y = Line2Start.Y
                        End If
                        If (Line2End.Y >= Line1Start.Y And Line2End.Y <= Line1End.Y) Then
                            Intersection.Y = Line2End.Y
                        End If
                    Else
                        If (Line2Start.Y <= Line1Start.Y And Line2Start.Y >= Line1End.Y) Then
                            Intersection.Y = Line2Start.Y
                        End If
                        If (Line2End.Y <= Line1Start.Y And Line2End.Y <= Line1End.Y) Then
                            Intersection.Y = Line2End.Y
                        End If
                    End If
                    Intersection.X = Line1Start.X
                End If
            Else
                If Not -1 * M1 = M2 Then
                    'Normal Case
                    Intersection.X = (B2 - B1) / (M1 - M2)
                    Intersection.Y = Line1Start.Y + M1 * (Intersection.X - Line1Start.X)
                Else
                    'the Lines are perpendicular (90&#176;)
                    'symetrical solution
                    SymPoint.Y = Line1Start.X * M2 + B2
                    Intersection.Y = Line1Start.Y + (SymPoint.Y - Line1Start.Y) / 2
                    Intersection.X = Intersection.Y * M1 + B1
                End If
            End If
            Return Intersection
        End Function
    Last edited by opus; Feb 15th, 2008 at 03:33 AM.
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  3. #3

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    I'll look it over this weekend when I get working on that module, but thanks for posting it, it'll save me a fair amount of time.
    My usual boring signature: Nothing

  4. #4
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Intersecting Lines

    I thought of a rather novel way to do this, though I think that opus's code is basically what you were looking for.

    My weird way involves translating and rotating the line segments with a dash of linear algebra, and then computing the possible intersection with only one or two "ifs". Logically it seems significantly more elegant than the slope-intercept method, but algorithmically they're probably nearly identical.

    If anyone's interested in the specifics I could try to flesh it out more
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    I think you should flesh it out more and post it on here just on the principle, but if you'd like encouragement, I'd be interested in seeing what you produce.

    As it turned out, I never even got close to dealing with this issue last weekend, despite spending two days working on the programs. Instead, I am totally bunged up over some networking issues, and may not get back to this piece for two more weeks. Very frustrating.
    My usual boring signature: Nothing

  6. #6
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Quote Originally Posted by jemidiah
    My weird way involves translating and rotating the line segments with a dash of linear algebra, and then computing the possible intersection with only one or two "ifs".

    I have no idea what it will take (CPU-cycle wise) to do the translation/rotation of all line segments, however IMHO it will take more then one or two Ifs to do the rest.

    Assume you have translated/rotated all lines, your line against all the others are checked does have y-values of 0 on both sides, x1 will be 0 as well, X2 will be the only one with a non zero value (or better a value of >0).
    You have to check for each line:
    Does the line have one Y-value at or above 0 and the other at or below 0?
    If that's true:
    If both X Values are between X1 and X2, there is an intersection.
    If one X-Value is outside and the other is inside (or better in between X1 and X2) the obvious would be to believe that there is an intersection. But that's not correct, since the intersection of the y=0 -line could be outside of X1 and X2 (use a line which is nearly paralell!).
    At this point I'll stop, because I don't think that all the needed Ifs will justify this other "weird" approach.
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  7. #7
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    I'm not sure this may be of any help to you. The function below calculates the intersection not of 2 straight lines but of 2 segments defined by 2 straight lines. Sorry I haven't used point structures -like opus did- which might have clarified the code quite a bit, still you can fix it yourself quite easily.

    Notice in the following code you can use either the parameter Alpha or Beta (though both are included) so you can modify the function removing either one. These parameters are optional as the function may be used just to check whether there is an intersection or not when the coordinates of the intersection are not needed.
    VB Code:
    1. Private Function SegmentIntersection(x1, y1, x2, y2, x3, y3, x4, y4, xint, yint, Optional Alpha, Optional Beta) As Boolean
    2.  
    3.     'Calculates the intersection (xint,yint) of the carrier straight lines
    4.     'of segments P1(x1,y1)-P2(x2,y2) and P3(x3,y3)-P4(x4,y4)
    5.    
    6.     'If the straight lines are parallel, there is
    7.     'no intersection and the function returns FALSE
    8.    
    9.     'If the intersection point belongs to both segments
    10.     'the function returns True, else it returns False
    11.    
    12.     Dim a As Single, b As Single, c As Single, p As Single, q As Single
    13.     Dim Gamma As Single
    14.  
    15.     SegmentIntersection = False
    16.    
    17.     a = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)
    18.     b = (x4 - x3) * (x4 - x3) + (y4 - y3) * (y4 - y3)
    19.     c = (x4 - x3) * (x2 - x1) + (y4 - y3) * (y2 - y1)
    20.     Gamma = a * b - c * c
    21.    
    22.     'If segments are parallel there is no intersection
    23.     If Gamma = 0 Then Exit Function
    24.        
    25.     p = (x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1)
    26.     q = (x3 - x1) * (x4 - x3) + (y3 - y1) * (y4 - y3)
    27.    
    28.     'In order to get to the intersection point, a vector
    29.     'must be added to the vector (x1,y1) with modulus
    30.     'equal to that of (x2-x1,y2-y1) times Alpha
    31.     Alpha = (b * p - c * q) / Gamma
    32.     'Same for Beta with respect to the other segment
    33.     Beta = (c * p - a * q) / Gamma
    34.    
    35.     'If the fractions belong to [0,1] then the intersections occur on the segments
    36.     'Else the segments do not intersect so return False
    37.     If Alpha >= 0 And Alpha <= 1 And Beta >= 0 And Beta <= 1 Then
    38.         xint = x1 + Alpha * (x2 - x1)
    39.         yint = y1 + Alpha * (y2 - y1)
    40.         'The following is ok as well (produces the same result):
    41.         'xint = x3 + Beta * (x4 - x3)
    42.         'yint = y3 + Beta * (y4 - y3)
    43.         SegmentIntersection = True
    44.     End If
    45.        
    46. End Function
    Last edited by krtxmrtz; Feb 22nd, 2008 at 09:16 AM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  8. #8
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    @krtxmrtz:
    your math is better than mine, since you need less Ifs to get a solution!

    However what is your reasoning for Alpha and Beta? You have them asan optional input to your function, but you use them as a local variable?
    Furthermore your function doesn't return the Intersection (you are not using Xint and Yint ByRef)?
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  9. #9
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Intersecting Lines

    The rotation is supposed to be accomplished by using the standard 2D rotation matrix, whose entries are all sines and cosines of the angle to be rotated. I was going to find the angle by taking the dot product of the segment and the positive x axis, which (when normalized) would yield the cosine of the angle of rotation, all without any trig. You can get the sine from the Pythagorean Theorem for an additional square root.

    I was also going to cut down on the if checks needed by just checking if the product of Y1 and Y2 was nonpositive--you would pass the "if" when either Y1 or Y2 is on the x axis, or when the sign flips. It rolls most of the conditions into one fairly elegant check; if the check fails, there is clearly no intersection.

    There are still two conceptual problems I haven't solved: first, if the first segment happens to be greater than 180 degrees from the x unit vector, my rotations won't work right (probably; it depends on the next issue). This can be solved easily by reversing the order of the points of the segment, but would require an additional if check if I can't come up with some nifty solution.

    Second, the more difficult problem: checking for a true intersection (as Opus had asked about). I have what might be a nifty idea around this, but I don't know if it can be optimized enough to require just one (simple) if check.

    ...I haven't really had time to work on this, but I really like the first part's simplicity. If I can find a nice algorithm at the end and the beginning this would be a much cleaner approach than the standard brute force algebra, but that's a big "if"
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

  10. #10
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    @jemidiah: I'm looking foreward to see your solution, however I think the math of krtxmrtz solution is clean and easy enough. I have to admit that I don't understand all the claculations, but I'm going to use it instead of my posted function.
    But I didin't start this thread!
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  11. #11
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    @krtxmrtz:
    your math is better than mine, since you need less Ifs to get a solution!

    However what is your reasoning for Alpha and Beta? You have them asan optional input to your function, but you use them as a local variable?
    Furthermore your function doesn't return the Intersection (you are not using Xint and Yint ByRef)?
    Yes, surprisingly enough they work as local variables, I don't know if they were supposed to, but the thing is it works. About the intersection, I'm passing the variables by reference, indeed, I really don't see your point. Convince yourself that the function does work.
    I don't know where I placed my math notes that I keep in a notebook, as soon as I can lay my paws on them I'll transcribe an explanation about the method I've used.
    By the way, if you implement the function using point structures it will become more readable (I'll do it myself one of these days)...
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  12. #12

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Wow, I'm glad I started this thread. I'm even (a little) glad that I got side tracked into solving some UDP networking issues. Got that problem solved, and it's posted in the networking section, so now I'm going to be back to working on this piece, and will be working on this part....maybe in a few hours, some non-programming stuff is getting in the way.
    My usual boring signature: Nothing

  13. #13
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Non programming stuff, what could be trhat? Are we talking real-world, does it still exist, I got ot believe that we're in the matrix ;-)


    @krtxmrtz:
    On the ByRef topic, it looks I'm getting more and more used to VB2005, what was/is the default in VB6 (I have forgotten!)

    I already made a function for VB2005, my Output is the Intersection itself, but I'm using two Boolean to tell wether the found intersection is Valid for the line-segment.
    The only check left to do is the case for parallel lines that are on top of each other, in my application I want to get a point result for that case.

    Code:
        Public Function Intersection(ByVal Line1Start As PointF, ByVal Line1End As PointF, ByVal Line2Start As PointF, ByVal Line2End As PointF, ByRef Check1 As Boolean, ByRef Check2 As Boolean) As PointF
            'Input Start and Endpoint of Lines
            'Output the Intersection and Check1/ Check2
            'Intersection only valid if at least one Check is true!
            'Math copyright by krtxmrtz!!
    
            'Calculates the intersection of the carrier straight lines
            'of segments Line1Start-Line1End and Line2Start-Line2End
    
            'If the straight lines are parallel, there is
            'no intersection and the function returns for both Check FALSE
            'If the intersection point belongs to both segments
            'the function returns True for both.
            Dim a As Single, b As Single, c As Single, p As Single, q As Single
            Dim Gamma As Single
            a = (Line1End.X - Line1Start.X) * (Line1End.X - Line1Start.X) + (Line1End.Y - Line1Start.Y) * (Line1End.Y - Line1Start.Y)
            b = (Line2End.X - Line2Start.X) * (Line2End.X - Line2Start.X) + (Line2End.Y - Line2Start.Y) * (Line2End.Y - Line2Start.Y)
            c = (Line2End.X - Line2Start.X) * (Line1End.X - Line1Start.X) + (Line2End.Y - Line2Start.Y) * (Line1End.Y - Line1Start.Y)
            Gamma = a * b - c * c
            'If segments are parallel there is no intersection
            If Gamma = 0 Then
    
                Check1 = False
                Check2 = False
                Exit Function
            End If
            p = (Line2Start.X - Line1Start.X) * (Line1End.X - Line1Start.X) + (Line2Start.Y - Line1Start.Y) * (Line1End.Y - Line1Start.Y)
            q = (Line2Start.X - Line1Start.X) * (Line2End.X - Line2Start.X) + (Line2Start.Y - Line1Start.Y) * (Line2End.Y - Line2Start.Y)
    
            'In order to get to the intersection point, a vector
            'must be added to the vector (line1Start) with modulus
            'equal to that of (line1end.x-line1start.x,line1send.y-line1stasrt.y) times Alpha
            Dim Alpha As Single = (b * p - c * q) / Gamma
            'Same for Beta with respect to the other segment
            Dim Beta As Single = (c * p - a * q) / Gamma
            Schnittpunkt.X = Line1Start.X + Alpha * (Line1End.X - Line1Start.X)
            Schnittpunkt.Y = Line1Start.Y + Alpha * (Line1End.Y - Line1Start.Y)
            'If the fractions belong to [0,1] then the intersections occur on the segments
            'Else the segments do not intersect 
            If Alpha >= 0 And Alpha <= 1 And Beta >= 0 And Beta <= 1 Then
                Check1 = True
                Check2 = True
            ElseIf (Alpha < 0 Or Alpha > 1) And Beta >= 0 And Beta <= 1 Then
                Check1 = False
                Check2 = True
            ElseIf Alpha >= 0 And Alpha <= 1 And (Beta < 0 Or Beta > 1) Then
                Check1 = True
                Check2 = False
            ElseIf (Alpha < 0 Or Alpha > 1) And (Beta < 0 Or Beta > 1) Then
                Check1 = False
                Check2 = False
            End If
        End Function
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  14. #14

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Well, I never got around to it, but ended up working on something else, instead. Covered lots of ground, just not this particular ground.

    The default in .NET is ByVal, but in VB6 it was ByRef. It got swapped.
    My usual boring signature: Nothing

  15. #15
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Quote Originally Posted by Shaggy Hiker
    The default in .NET is ByVal, but in VB6 it was ByRef. It got swapped.
    Thanks Shaggy.

    BTW, although I'm not 100%-sure, I believe that the Math approach from krtxmrtz is working in the way you where thinking. Look at the final check, where Alpha and Beta are checked wether they are within [0,1].
    I hope he [krtxmrtz] finds his math notes.
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  16. #16
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    ...@krtxmrtz:
    On the ByRef topic, it looks I'm getting more and more used to VB2005, what was/is the default in VB6 (I have forgotten!)
    I think the default is ByRef.
    Quote Originally Posted by opus
    ...
    The only check left to do is the case for parallel lines that are on top of each other, in my application I want to get a point result for that case.
    OK, hang on...
    I seem to have mislaid my notes, however I decided to derive the whole thing again. It turns out to be much easier than the code I posted but I found a flaw: you actually need to calculate both alpha and beta (yet the code seems to work for me in the present shape that I posted above), therefore just wait a little longer and I'll post my derivation, then you can check it up thoroughly.
    Btw, the case where both segments are on the same carrier line is easy to pick up.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  17. #17
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Here's a word document with my derivation. I wrote it a little hurriedly so please let me know if there's some typo, mistake or inconsistency of any kind.

    I don't know where the heck the code in post #7 came from, probably it's correct but I have yet to study it in depth.
    Attached Files Attached Files
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  18. #18
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Quote Originally Posted by krtxmrtz
    I don't know where the heck the code in post #7 came from, probably it's correct but I have yet to study it in depth.
    I feel better now, it doesn't happen to me only!
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  19. #19
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Hey krtxmrtz,
    I used your document to rework the Function (only in VB2005, if you need it in VB6 let me know).
    I haven't completed the checks in case of LineSegments on a Line, maybe soemone else could step in :-)

    Code:
       Private Function Intersection(ByVal Line1Start As PointF, ByVal Line1End As PointF, ByVal Line2Start As PointF, ByVal Line2End As PointF, ByRef Check1 As Boolean, ByRef Check2 As Boolean) As PointF
            'Input Line1Start , Line1End, Line2Start, Line2End
            'Output Booleans Check1/Check2 are True if Intersection exists on both LineSegments!
            'If an intersection is found outside a segment, the respective Check will be False!
            Dim Determinante As Single
            Dim DeterminanteS As Single
            Dim DeterminanteT As Single
            Dim S As Single
            Dim T As Single
            Determinante = (Line1End.Y - Line1Start.Y) * (Line2End.X - Line2Start.X) - (Line1End.X - Line1Start.X) * (Line2End.Y - Line2Start.Y)
            DeterminanteS = (Line2Start.Y - Line1Start.Y) * (Line2End.X - Line2Start.X) - (Line2Start.X - Line1Start.X) * (Line2End.Y - Line2Start.Y)
            DeterminanteT = (Line2Start.Y - Line1Start.Y) * (Line1End.X - Line1Start.X) - (Line2Start.X - Line1Start.X) * (Line1End.Y - Line1Start.Y)
            If Determinante = 0 Then
                'The LineSegments are either parallel or identical
                If DeterminanteS <> 0 Or DeterminanteT <> 0 Then
                    'the LineSegments only parallel, but not on the same Line, no Intersection!
                    Check1 = False
                    Check2 = False
                    Exit Function
                Else
                    'both LineSegments are on the same Line, however they could be seperated!
                    'TOBE COMPLETED!!!
                End If
            Else
                S = DeterminanteS / Determinante
                If S < 0 Or S > 1 Then
                    'Intersection is outside of Line1Segment!
                    Check1 = False
                Else
                    Check1 = True
                End If
                T = DeterminanteT / Determinante
                If T < 0 Or T > 1 Then
                    'Intersection is outside of Line2Segment!
                    Check2 = False
                Else
                    Check2 = True
                End If
                Intersection.X = Line1Start.X + S * (Line1End.X - Line1Start.X)
                Intersection.Y = Line1Start.Y + S * (Line1End.Y - Line1Start.Y)
            End If
        End Function
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  20. #20
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    Hey krtxmrtz,
    I used your document to rework the Function (only in VB2005, if you need it in VB6 let me know)...
    It certainly looks more readable now... and I hope it works!

    No problem about converting to VB6, I wrote this function long ago before I even knew that such a thing as UDT existed... Next time I need to use the function I will do the conversion myself. Thanks anyway.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  21. #21

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Looks good.

    Last night I realized that my original question had fallen out of date. I realized that I have a totally different way to solve the original question that has nothing to do with line segments, but with logic. However, I now believe that the issue of line segments will be an issue in possibly two other modules in the code.
    My usual boring signature: Nothing

  22. #22
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    I'm think I have a way to check for the case when the LineSegments are parallel and are on the same Line.
    PseudoCode:
    For Each EndPoint of LineSegment A check wether the distance to each EndPoint of LineSegment B is equal or less then the Segment distance of LineSegment B. If this is True (for both EndPoints of LineSegment B) the Point is on LineSegment B.

    Actually we don't have to calculate the correct distance-value, we can ommit the SquareRooting because we only check the relation between those values.

    That way we need to calculate 6 Distances (without the SquareRoot) and do 4 If-Thens Checks.

    You'll have to wait until Friday or Saturday to have that incooperated into the Function posted above. (Some real-live problems have to be solved!)
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  23. #23

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    See? Real life gets in the way.

    I won't be getting to this part for a couple of months at this rate. I realized last night that before the robot creates a track that crosses the line segment, the question of whether or not it CAN cross the line segment will have been answered. Though as I write this, it occured to me that I might be able to use the code MUCH sooner, because it would allow me to determine whether or not the bounding box around an object crosses a line segment. Four line segments, and if any one of them touches or crosses, then that's all I need to know.

    By the way, after looking at that code, I decided to test whether (X-x)*(X-x) (as you have) is faster than (X-x)^2. I put both into my test app, and the way you have it was VASTLY faster. Therefore, don't use ^ unless you really need to. This may not be true if you are doing anything other than simply squaring the argument.
    My usual boring signature: Nothing

  24. #24
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    I'm think I have a way to check for the case when the LineSegments are parallel and are on the same Line...
    Wait a minute, this case was already dealt with in the document I attached to post #17, wasn't it? First you test whether the segments are parallel. If they are then you additionally test if they are on the same carrier line.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  25. #25
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by Shaggy Hiker
    ...By the way, after looking at that code, I decided to test whether (X-x)*(X-x) (as you have) is faster than (X-x)^2. I put both into my test app, and the way you have it was VASTLY faster. Therefore, don't use ^ unless you really need to. This may not be true if you are doing anything other than simply squaring the argument.
    I think this is always true no matter what the variable type is. The more sophisticated the operation, the longer it takes. So * is faster than ^ but I haven't checked if, say, x + x + x is faster than 3*x, not very useful though, even if it is.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  26. #26
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Quote Originally Posted by Shaggy Hiker
    By the way, after looking at that code, I decided to test whether (X-x)*(X-x) (as you have) is faster than (X-x)^2. I put both into my test app, and the way you have it was VASTLY faster. Therefore, don't use ^ unless you really need to. This may not be true if you are doing anything other than simply squaring the argument.
    Exactly this topic has been discussed AND benchmarked in depth somewhere in VBForums (I'd guess 3 or 4 years ago), and with the same result you found!
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  27. #27
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Quote Originally Posted by krtxmrtz
    First you test whether the segments are parallel. If they are then you additionally test if they are on the same carrier line.
    I see/understand the test for parallel, but I don't see/understand any checking for the same carrier line (maybe it's my stupidity!)
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  28. #28
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    I see/understand the test for parallel, but I don't see/understand any checking for the same carrier line (maybe it's my stupidity!)
    Well, if they are parallel, check if the coordinates of, say, P2 produce an identity when substituted in the equation of the carrier line of segment P3-P4, then P2 (and of course P1) will be on that line.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  29. #29
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    I guess you are refering to this line:
    (y3 – y1)(x2 – x1) = (x3 – x1)(y2 – y1)

    This will be true if Point x3;y3 is on the line that goes through the points x1;y2 and x2;y2, however we are looking for a check that tells wether x3;y3 is between those points!

    For example:
    Line 1
    x1;y1 [0;0]
    x2;y2 [0;2]
    Line 2
    x3;y4 [0;3]
    x4;y4 [0;4]
    Both lines are parallel, but they are NOT overlapping.
    Check for parallel:
    (y4 – y3)(x2 – x1) = (x4 – x3)(y2 – y1)
    (4-3)(0-0)=(0-0)(2-0)
    0=0 hence parallel

    Check if x3;y3 is on Line
    (y3 – y1)(x2 – x1) = (x3 – x1)(y2 – y1)
    (3-0)(0-0)=(0-0)(2-0)
    0=0
    That would tell they are overlapping, which they don't!!
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  30. #30

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Quote Originally Posted by krtxmrtz
    I think this is always true no matter what the variable type is. The more sophisticated the operation, the longer it takes. So * is faster than ^ but I haven't checked if, say, x + x + x is faster than 3*x, not very useful though, even if it is.
    I don't think I'd benchmark that one. The answer is this:

    If x is an integer type then

    X+X+X is FAR faster than 3*x

    if x is a decimal type then

    X+X+X should be slower than 3*x

    The reason is that for integer math, the addition is in the RISC subset of the instructions on an x86 processor, so it is among the fastest of all operations, whereas the integer multiplication, while still in the instruction set of the processor, is one of the slower instructions. You can't get actual timing anymore, because there are so many factors going into the actual timing of the instructions that the exact timing for any particular instruction is kind of fluid.

    For the floating point, addition is very tough, while multiplication is relatively easy. Both are off on the FPU of the CPU, and the timing for them is a bit vague, as well, but back on the first pentiums, floating point mult and div was supposed to be faster than floating point addition or subtraction (my tests at the time confirmed that, though I have recently found that it may not be true any longer). Integer addition and subtraction should be far faster than any of the others, though.
    My usual boring signature: Nothing

  31. #31

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Quote Originally Posted by opus
    Exactly this topic has been discussed AND benchmarked in depth somewhere in VBForums (I'd guess 3 or 4 years ago), and with the same result you found!
    I vaguely remember the subject, and may have participated, since it's the kind of topic I would tend to try out.
    My usual boring signature: Nothing

  32. #32
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    ...however we are looking for a check that tells wether x3;y3 is between those points!
    ...
    Oh, is that what you meant!? Sorry I hadn't grasped it.

    Well, once you're sure they are parallel and on the same carrier line, all that's left to do is check whether or not the following is true:

    x1 <= x3 AND x1 <= x4 AND x2 >= x3 AND x2 >= x4

    or alternatively you can do the same test using y instead of x. Of course, if it's true for x then it will be for y and vice versa since they are on the same line.

    This is the case the segment [P1,P2] contains the segment [P3,P4]. You can easily test for the opposite case.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  33. #33
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Intersecting Lines

    Doing the check for that situation would need several IFs, since one line-segment could be only overlapping. You have to make sure that the points are in some order for decrease the needed checks [what if x1 >x2 in your example?].

    I would go for this check in the complete function:
    Code:
       Private Function Intersection(ByVal Line1Start As PointF, ByVal Line1End As PointF, ByVal Line2Start As PointF, ByVal Line2End As PointF, ByRef Check1 As Boolean, ByRef Check2 As Boolean) As PointF
            'Input Line1Start , Line1End, Line2Start, Line2End
            'Output Booleans Check1/Check2 are True if Intersection exists on both LineSegments!
            'If an intersection is found outside a segment, the respective Check will be False!
            Dim Determinante As Single
            Dim DeterminanteS As Single
            Dim DeterminanteT As Single
            Dim Dist1 As Single
            Dim Dist2 As Single
            Dim Dist11 As Single
            Dim Dist12 As Single
            Dim Dist21 As Single
            Dim Dist22 As Single
            Dim S As Single
            Dim T As Single
            Determinante = (Line1End.Y - Line1Start.Y) * (Line2End.X - Line2Start.X) - (Line1End.X - Line1Start.X) * (Line2End.Y - Line2Start.Y)
            DeterminanteS = (Line2Start.Y - Line1Start.Y) * (Line2End.X - Line2Start.X) - (Line2Start.X - Line1Start.X) * (Line2End.Y - Line2Start.Y)
            DeterminanteT = (Line2Start.Y - Line1Start.Y) * (Line1End.X - Line1Start.X) - (Line2Start.X - Line1Start.X) * (Line1End.Y - Line1Start.Y)
            If Determinante = 0 Then
                'The LineSegments are either parallel or identical
                If DeterminanteS <> 0 Or DeterminanteT <> 0 Then
                    'the LineSegments only parallel, but not on the same Line, no Intersection!
                    Check1 = False
                    Check2 = False
                    Exit Function
                Else
                    'both LineSegments are on the same Line, however they could be seperated!
                    'the NEW Check!
                    'both LineSegments are on the same Line, however they could be seperated!
                    'Two LineSegments on a identical Line have an overlapp if the distance of one EndPoint to
                    'the Start and EndPoint of the other LineSegment is less then the distance of this other LineSegment!
                    'for all distances, the squareroot is ommited, because only the relation between distances is checked!
                   'Length of Line1
                   Dist1 = (Line1End.X - Line1Start.X) * (Line1End.X - Line1Start.X) + (Line1End.Y - Line1Start.Y) * (Line1End.Y - Line1Start.Y)
                   'Length of Line2
                   Dist2 = (Line2End.X - Line2Start.X) * (Line2End.X - Line2Start.X) + (Line2End.Y - Line2Start.Y) * (Line2End.Y - Line2Start.Y)
                   'Distance from Line1Start to Line2Start 
                   Dist11 = (Line1Start.X - Line2Start.X) * (Line1Start.X - Line2Start.X) + (Line1Start.Y - Line2Start.Y) * (Line1Start.Y - Line2Start.Y)
                   'Distance from Line1Start to Line2End 
                   Dist12 = (Line1Start.X - Line2End.X) * (Line1Start.X - Line2End.X) + (Line1Start.Y - Line2End.Y) * (Line1Start.Y - Line2End.Y)
                  'Distance from Line1End to Line2End 
                   Dist21 = (Line2End.X - Line1End.X) * (Line2End.X - Line1End.X) + (Line2End.Y - Line1End.Y) * (Line2End.Y - Line1End.Y)
                  'Distance from Line1End to Line2Start 
                   Dist22 = (Line2Start.X - Line1End.X) * (Line2Start.X - Line1End.X) + (Line2Start.Y - Line1End.Y) * (Line2Start.Y - Line1End.Y)
                   'Check Distance of Line2Start to Line1Start/Line1End against Line1!
                   If Dist11 <= Dist1 And Dist22 <= Dist1 Then
                        Intersection.X = Line2Start.X
                        Intersection.Y = Line2Start.Y
                        Check1 = True
                        Check2 = True
                        Exit Function
                   End If
                   'Check Distance of Line2End to Line1Start/Line1End against Line1!
                   If Dist12 <= Dist1 And Dist21 <= Dist1 Then
                        Intersection.X = Line2End.X
                        Intersection.Y = Line2End.Y
                        Check1 = True
                        Check2 = True
                        Exit Function
                   End If
                   'Check Distance of Line1Start to Line2Start/Line2Start against Line2!
                   If Dist11 <= Dist2 And Dist12 <= Dist2 Then
                        Intersection.X = Line1Start.X
                        Intersection.Y = Line1Start.Y
                        Check1 = True
                        Check2 = True
                        Exit Function
                   End If
                   'Check Distance of Line1End to Line1Start/Line2End against Line2!
                   If Dist21 <= Dist2 And Dist22 <= Dist2 Then
                        Intersection.X = Line1End.X
                        Intersection.Y = Line1End.Y
                        Check1 = True
                        Check2 = True
                        Exit Function
                   End If
                   'None of the Segments have Intersections!
                   Check1 = False
                   Check2 = False
                   Exit Function
                End If
            Else
                S = DeterminanteS / Determinante
                If S < 0 Or S > 1 Then
                    'Intersection is outside of Line1Segment!
                    Check1 = False
                Else
                    Check1 = True
                End If
                T = DeterminanteT / Determinante
                If T < 0 Or T > 1 Then
                    'Intersection is outside of Line2Segment!
                    Check2 = False
                Else
                    Check2 = True
                End If
                Intersection.X = Line1Start.X + S * (Line1End.X - Line1Start.X)
                Intersection.Y = Line1Start.Y + S * (Line1End.Y - Line1Start.Y)
            End If
        End Function
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  34. #34
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by opus
    Doing the check for that situation would need several IFs, since one line-segment could be only overlapping. You have to make sure that the points are in some order for decrease the needed checks [what if x1 >x2 in your example?]...
    I forgot about that in my last post. But the usual way I do it in any situation is this: regardless of whether or not x1 is greater than x2 you can do it a few simple statements using the sgn function. For example, to test if x3 lies in between x1 and x2,
    VB Code:
    1. s = sgn(x2 - x1)
    2. If x1*s <= x3*s AND x2*s >= x3*s Then
    3. '...
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  35. #35

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    Quote Originally Posted by krtxmrtz
    I think this is always true no matter what the variable type is. The more sophisticated the operation, the longer it takes. So * is faster than ^ but I haven't checked if, say, x + x + x is faster than 3*x, not very useful though, even if it is.
    Just for grins, I ran this test. x+x+x should have been FAR faster than 3*x, but in VB.NET 2005, it took about twice as long, as if there was no difference between multiplication and addition in the underlying code. The IL for the two tests looked just the way I expected it to.

    Then I tested whether 3+3+3 was faster than 3*x, and it was. However, it was faster because 3+3+3 generated the code: Move 9 to memory location. Therefore, the compiler was able to optimize away the entire operation.

    However, I then tested x+x+x vs 3*x for double, rather than integer, values, and the two equations took exactly the same time, both of which were faster than the integer version. That's a bit disturbing. Floating point math should be slower, but it's faster. Integer addition should be faster than multiplication, but it looks like the cost for an integer operation is constant, so the number of operations is more important than what the operation is. Floating point math appears to be handled more effectively than the integer math, regardless of what kind of operation.

    In C++, I had written an approximation of the Pythagorean Theorem that used only a couple additions and a pair of bit shifts, all of which are particularly fast on the x86. After doing these tests, I guess that I might as well stick with the real algorithm as long as I am working in .NET.
    My usual boring signature: Nothing

  36. #36
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Intersecting Lines

    Quote Originally Posted by krtxmrtz
    ...
    I don't know where I placed my math notes that I keep in a notebook...
    I've finally found them!!!

    I have attached a pdf file with my derivation of the distance between 2 segments (starting at page 2) and as you will see I made it damn complicated... The other solution I gave in post #17 is much easier. Still I knew the code in post #7 worked and that I had a derivation for it.
    Attached Images Attached Images
    Last edited by krtxmrtz; Mar 27th, 2008 at 06:39 AM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  37. #37

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Intersecting Lines

    My project was seriously derailed about two weeks back when I discovered that the hardware had nowhere near the accuracy I had understood it to have. It was good to see this discussion, and it may be that I eventually will even use it, but for now, I am off on an AI adventure. With my sensors proving to be wildly innacurate beyond fairly short range, I am working on a fuzzy logic mapping design which is likely to totally remove any work with lines or line segments of any sort. At best, my "eyes" can determine that there is something out there at a certain distance from the eye, with no direction other than the arc of sight. In other words, I can know that something is about 3m away, and it lies on an arc of maybe as little as 30 degrees, but where on that arc it lies I cannot say.

    I've come up with a fuzzy mapping routine (not yet implemented) which should eventually figure out where objects are, but my original intent was to look at gaps between objects, which won't be meaningful anymore now that the world will be nothing more than a probability contour.

    Makes life more interesting, though.
    My usual boring signature: Nothing

  38. #38
    Frenzied Member
    Join Date
    Jun 2006
    Posts
    1,098

    Re: Colinear Line Segment Overlap

    Quote Originally Posted by krtxmrtz
    For example, to test if x3 lies in between x1 and x2,
    VB Code:
    1. s = sgn(x2 - x1)
    2. If x1*s <= x3*s AND x2*s >= x3*s Then
    3. '...
    Another way to make the same check:
    Code:
    If (x3 - x1) * (x3 - x2) <= 0 Then '...
    Of course, you still have to make several checks to determine if there is any overlap of two colinear line segments. I have come up with a simpler check by comparing the length of the segments to the distance between their midpoints. If their combined length is at least twice the distance between their midpoints, then an overlap must occur, given that the segments are colinear.
    Code:
    If Abs(x1 - x2) + Abs(x3 - x4) >= Abs(x1 + x2 - x3 - x4) Then '...
    Conversely, if their combined length is less than twice the distance between their midpoints, than an overlap cannot occur. This is certainly true even when the segments are not colinear. As such, the above test of the segments' horizontal projections can be combined with a similar test of their vertical projections to rule out the possibility of an intersection when the rectangular regions defined by the segments do not overlap.

  39. #39
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: Colinear Line Segment Overlap

    Quote Originally Posted by Logophobic
    Another way to make the same check:
    ...
    This is much easier, indeed!
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width