How can I tell if a point belongs to a certain line?

前端 未结 11 2200
你的背包
你的背包 2020-12-01 08:22

How can I tell if a point belongs to a certain line?

Examples are appreciated, if possible.

11条回答
  •  Happy的楠姐
    2020-12-01 08:43

    I just wrote an function which handles a few extra requirements since I use this check in a drawing application:

    • Fuzziness - There must be some room for error since the function is used to select lines by clicking on them.
    • The line got an EndPoint and a StartPoint, no infinite lines.
    • Must handle straight vertical and horizontal lines, (x2 - x1) == 0 causes division by zero in the other answers.
    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;            
    }
    

提交回复
热议问题