Does a line contain a point

后端 未结 3 1899
野趣味
野趣味 2020-12-21 17:00

I want the user to be able to drag the edges of a square around the canvas. With my current solution it works but has glitches, sometimes an edge cannot be selected. Is ther

相关标签:
3条回答
  • 2020-12-21 17:25

    use the line equation y = mx + b to find out if the point is on a line

    float EPSILON = 0.001f;
    
    public boolean isPointOnLine(Point linePointA, Point linePointB, Point point) {
        float m = (linePointB.y - linePointA.y) / (linePointB.x - linePointA.x);
        float b = linePointA.y - m * linePointA.x;
        return Math.abs(point.y - (m*point.x+b)) < EPSILON);
    }
    
    0 讨论(0)
  • 2020-12-21 17:28

    You could define 8 Rect to check against - the 4 sides and 4 corners (so you can move 2 edges at once). The lines of the edge should have a width for the touchable area.

    Define a Point centred on your touch event, there are then methods for checking if a rect contains a point.

    0 讨论(0)
  • 2020-12-21 17:38

    Great piece of code by @tyczj !
    I added a use-case to handle vertical lines, which gives me the following code fragment:

    public boolean isPointOnLine(PointF lineStaPt, PointF lineEndPt, PointF point) {
        final float EPSILON = 0.001f;
        if (Math.abs(staPt.x - endPt.x) < EPSILON) {
            // We've a vertical line, thus check only the x-value of the point.
            return (Math.abs(point.x - lineStaPt.x) < EPSILON);
        } else {
            float m = (lineEndPt.y - lineStaPt.y) / (lineEndPt.x - lineStaPt.x);
            float b = lineStaPt.y - m * lineStaPt.x;
            return (Math.abs(point.y - (m * point.x + b)) < EPSILON);
        }
    }
    

    Also a piece of code to check if a point lies on a line-segment:

    public boolean isPointOnLineSegment(PointF staPt, PointF endPt, PointF point) {
        final float EPSILON = 0.001f;
        if (isPointOnLine(staPt, endPt, point)) {
            // Create lineSegment bounding-box.
            RectF lb = new RectF(staPt.x, staPt.y, endPt.x, endPt.y);
            // Extend bounds with epsilon.
            RectF bounds = new RectF(lb.left - EPSILON, lb.top - EPSILON, lb.right + EPSILON, lb.bottom + EPSILON);
            // Check if point is contained within lineSegment-bounds.
            return bounds.contains(point.x, point.y);
        }
        return false;
    }
    
    0 讨论(0)
提交回复
热议问题