How can I tell if a point belongs to a certain line?
Examples are appreciated, if possible.
You should be able to plug in the x and y values for both points, and if both make the equation y < mx + b or both make it y > mx + b, they are on the same side. If either point satisfies the equation (y = mx + b), that point is on the line.
If the line equation is y=ax+b and the coordinates of a point is (x0,y0) then compare y0 and ax0+b, for example if y0>ax0+b then the point is above the line, etc.
In the simplest form, just plug the coordinates into the line equation and check for equality.
Given:
Point p (X=4, Y=5)
Line l (Slope=1, YIntersect=1)
Plug in X and Y:
Y = Slope * X + YIntersect
=> 5 = 1 * 4 + 1
=> 5 = 5
So yes, the point is on the line.
If your lines are represented in (X1,Y1),(X2,Y2) form, then you can calculate slope with:
Slope = (y1 - y2) / (x1-x2)
And then get the Y-Intersect with this:
YIntersect = - Slope * X1 + Y1;
Edit: I fixed the Y-Intersect (which has been X1 / Y1 ...)
You'll have to check that x1 - x2
is not 0
. If it is, then checking if the point is on the line is a simple matter of checking if the Y value in your point is equal to either x1
or x2
. Also, check that the X of the point is not 'x1' or 'x2'.
I just wrote an function which handles a few extra requirements since I use this check in a drawing application:
private const double SELECTION_FUZZINESS = 3;
internal override bool ContainsPoint(Point point)
{
LineGeometry lineGeo = geometry as LineGeometry;
Point leftPoint;
Point rightPoint;
// Normalize start/end to left right to make the offset calc simpler.
if (lineGeo.StartPoint.X <= lineGeo.EndPoint.X)
{
leftPoint = lineGeo.StartPoint;
rightPoint = lineGeo.EndPoint;
}
else
{
leftPoint = lineGeo.EndPoint;
rightPoint = lineGeo.StartPoint;
}
// If point is out of bounds, no need to do further checks.
if (point.X + SELECTION_FUZZINESS < leftPoint.X || rightPoint.X < point.X - SELECTION_FUZZINESS)
return false;
else if (point.Y + SELECTION_FUZZINESS < Math.Min(leftPoint.Y, rightPoint.Y) || Math.Max(leftPoint.Y, rightPoint.Y) < point.Y - SELECTION_FUZZINESS)
return false;
double deltaX = rightPoint.X - leftPoint.X;
double deltaY = rightPoint.Y - leftPoint.Y;
// If the line is straight, the earlier boundary check is enough to determine that the point is on the line.
// Also prevents division by zero exceptions.
if (deltaX == 0 || deltaY == 0)
return true;
double slope = deltaY / deltaX;
double offset = leftPoint.Y - leftPoint.X * slope;
double calculatedY = point.X * slope + offset;
// Check calculated Y matches the points Y coord with some easing.
bool lineContains = point.Y - SELECTION_FUZZINESS <= calculatedY && calculatedY <= point.Y + SELECTION_FUZZINESS;
return lineContains;
}
The best way to determine if a point R = (rx, ry) lies on the line connecting points P = (px, py) and Q = (qx, qy) is to check whether the determinant of the matrix
{{qx - px, qy - py}, {rx - px, ry - py}},
namely (qx - px) * (ry - py) - (qy - py) * (rx - px) is close to 0. This solution has several related advantages over the others posted: first, it requires no special case for vertical lines, second, it doesn't divide (usually a slow operation), third, it doesn't trigger bad floating-point behavior when the line is almost, but not quite vertical.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With