Point on Line Segment

BlitzPlus Forums/BlitzPlus Programming/Point on Line Segment

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Here is a way to do it: First, suppose the line has coordinates (x1,y1) and (x2,y2), and that the point you are interested in is at (x3,y3). If the point is somewhere along the path of the line, then it must fit between the pairs (x1,y1) and (x2,y2). If it doesn't then you are not on the same line (although if the line were extended, it might still cross your point).

So, for the first test, you want to know of x3 is between x1 and x2. Then you want to know if y3 is between y1 and y2. Only if both those answers are true would it be possible to tell if the point lies in the vicinity of the line.

But wait, that isn't enough. The coordinates (x1,y1) and (x2,y2) not only detail a straight line, but they are also the coordinates for a rectangle that could be constructed with the opposite end points at those locations. In other words, all we have extablished so far is that the point lies within the rectangle formed between those end points. This would only be a line if the points were either vertical or horizontal to each other. So next we check to see if x1=x2 or y1=y2. If so, then it is a straight line and we have a match.

But the line is not vertical or horizontal, so now we want to see if the slope of a line constructed between (x3,y3) and (x1,y1) matches the slope of a line constructed between (x1,y1) and (x2,y2). We saved this step for last for two reasons: (1) It involves division, which is slower than just comparing values to each other, and (2) with division we have to be careful not to divide by zero, so some additional checks are required,

What we are looking at is that if two lines have the same slope (ratio between their respective X and Y coordinates), and share the same end point, and the other end point lies somewhere this side of the far endpoint, then the shorter line is a subpart of the longer line, and the points along both lines where they coincide are points on the other line as well.

So how would this whole thing look?

online=false
if x3>=x1 and x2<=x2 or x3<=x1 and x3>=x2 then
;has to be within the right area
if y3>=y1 and y3<=y2 or y3<=y1 and y3>=y2 then
;now we are in the same rectangle or line
if x1=x2 or y1=y2 then
;vertical or horizontal line, so yes!
online=true
elseif x1=x3 and y1=y3 or x2=x3 and y2=y3 then
;lies right on an end point, so still yes!
online=true
elseif (x1-x3)/(y1-y3) = (x1-x2)/(y1-y2) then
;okay we have a slope match, so yes!
online=true
elseif (x2-x3)/(y2-y3) = (x1-x2)/(y1-y2) then
;okay, we check the slope facing the other way
online=true ;in case we were pointed wrong!
endif
endif
endif

And that should do it. Now if you want to get rid of the divides, you can transpose the equations by taking the divisors across the equal signs and performing multiplies instead. If you do this, then it is unnecessary to test to
avoid division by zero. That code would look like this:

if (x1-x3)*(y1-y2) = (x1-x2)*(y1-y3) then
;okay we have a slope match, so yes!
online=true
elseif (x2-x3)*(y1-y2) = (x1-x2)*(y2-y3) then
;okay, we check the slope facing the other way
online=true ;in case we were pointed wrong!
endif

So if you really reason it out a bit, the problem can be a lot easier to solve than you expected.