1

Simple problem - find if a point is inside a convex Polygon. There is algorithm described yet due to be beeng an in Wolfram language and I ve got something wrong. This is what I have:

private static bool PointInside2D(Vector2 point, Vector2 lineStart, Vector2 lineEnd) {
    var v1 = lineStart - point;
    var edge = lineStart - lineEnd;
    return !(edge.x * v1.y - edge.y * v1.x < 0);
}

private static bool PointInsideRect2D(Vector2 point, IList<Vector2> rect) {
    var lastPoint = rect.Count - 1;
    bool? lastResult = null;
    for (var i = 0; i < lastPoint; ++i) {
        if (lastResult == null) {
            lastResult = PointInside2D(point, rect[i], rect[i + 1]);
        }
        else {
            if (lastResult != PointInside2D(point, rect[i], rect[i + 1])) {
                return false;
            }
        }
    }
    return lastResult == PointInside2D( point, rect[lastPoint], rect[0] );
}

and it does not work sadly... I looked at some refrence implementations here tried them seems also not to work..

test data I use is for convex:

 [(262.8, 669.1); (1623.9, 718.2); (200.4, 895.4); (1817.8, 1540.8)]

and (288, 815) and (1078, 890) as test points.

Can any one explain what I've got wrong in that algorithm/its implementations?

Community
  • 1
  • 1
Rella
  • 65,003
  • 109
  • 363
  • 636

1 Answers1

2

I believe your algorithm works correctly. It tests, if tested point lies on the same side (left or right) of all edges of polygon. But it requires, that all points in polygon declaration are sorted in clockwise or anti-clockwise order, that is not true for [(262.8, 669.1); (1623.9, 718.2); (200.4, 895.4); (1817.8, 1540.8)].

When I changed order of points in polygon, following program seem to return correct results:

    public static void Main()
    {
        Vector2 p1 = new Vector2(288, 815);
        Vector2 p2 = new Vector2(1078, 890);

        //Please notice order of points is changed to clockwise
        IList<Vector2> Polygon = new List<Vector2>(new Vector2[] { new Vector2(262.8f, 669.1f), new Vector2(200.4f, 895.4f), new Vector2(1817.8f, 1540.8f), new Vector2(1623.9f, 718.2f) });

        bool p1Result = PointInsideRect2D(p1, Polygon);
        bool p2Result = PointInsideRect2D(p2, Polygon);
    }

    private static bool PointInside2D(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
    {
        var v1 = lineStart - point;
        var edge = lineStart - lineEnd;
        return !(edge.X * v1.Y - edge.Y * v1.X < 0);
    }

    private static bool PointInsideRect2D(Vector2 point, IList<Vector2> rect)
    {
        var lastPoint = rect.Count - 1;
        bool? lastResult = null;
        for (var i = 0; i < lastPoint; ++i)
        {
            if (lastResult == null)
            {
                lastResult = PointInside2D(point, rect[i], rect[i + 1]);
            }
            else
            {
                if (lastResult != PointInside2D(point, rect[i], rect[i + 1]))
                {
                    return false;
                }
            }
        }
        return lastResult == PointInside2D(point, rect[lastPoint], rect[0]);
    }
Ňuf
  • 6,027
  • 2
  • 23
  • 26