• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • ✅ The POLL for Hive's Texturing Contest #33 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!

Check if x/y coordinates (or point) are inside of a parallelogram

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 68
Joined
Aug 10, 2018
Messages
7,129
Hey gang, hopefully someone can help me out with this one.
I'm trying to create a function that will check if a pair of X/Y coordinates are inside of a parallelogram.

example.png


So I have 4 Points, A, B, C and D. They each contain a pair of X/Y coordinates.
My goal is to check if a given pair of x/y coordinates are inside of this shape and return true of false:
Lua:
function IsInsideShape(x, y, a, b, c, d)
    -- fancy math goes here to check if x/y are inside of these four points (a,b,c,d)
    return true/false
end

Here's what I have been trying to get to work (found it online). I converted it from Python to C# (I'm using WCSharp):
(Note: poly is just an array of Points that contain x/y values)
Code:
        public static bool CoordsInPolygon(float x, float y, Point[] poly) {
            int n = poly.Length;
            int mod;
            float xinters;
            float p1x = poly[0].X;
            float p1y = poly[0].Y;

            for (int i = 0; i < n + 1; i++) {
                mod = i % n;
                float p2x = poly[mod].X;
                float p2y = poly[mod].Y;
                if (y > Math.Min(p1y, p2y)) {
                    if (y <= Math.Max(p1y, p2y)) {
                        if (x <= Math.Max(p1x, p2x)) {
                            if (p1y != p2y) {
                                xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x;
                                if (p1x == p2x || x <= xinters) {
                                    return true;
                                }
                            }
                        }
                    }
                }
                p1x = p2x;
                p1y = p2y;
            }
            return false;
        }
I'm not sure if there's a certain order in how I should index poly or what...

Here's the Python code that I based it on:
Code:
def point_inside_polygon(x,y,poly):

    n = len(poly)
    inside =False

    p1x,p1y = poly[0]
    for i in range(n+1):
        p2x,p2y = poly[i % n]
        if y > min(p1y,p2y):
            if y <= max(p1y,p2y):
                if x <= max(p1x,p2x):
                    if p1y != p2y:
                        xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
                    if p1x == p2x or x <= xinters:
                        inside = not inside
        p1x,p1y = p2x,p2y

    return inside
Thanks for any and all help!
 
Last edited:
I can suggest a couple solutions:

1. Test if the test point is not in the convex hull of all 5 points Graham scan - Wikipedia
2. Rotate all points about the parallelogram's orientation and then simply test that the result test point is inside the result axis-oriented rect
 

Uncle

Warcraft Moderator
Level 68
Joined
Aug 10, 2018
Messages
7,129
Thanks, guys. I'll have to look into Quadrilateral, that looks like exactly what I need. The other stuff will probably go over my head but I'll at least give it a shot!

Edit:
Ended up using a function found in that Quadrilateral link and recreated it in C#:
Code:
        public static bool IsPointInQuadrilateral(float px, float py, float ax, float ay, float bx, float by, float cx, float cy, float dx, float dy) {
            float nx;
            float ny;
            float edge;
            nx = bx - ax;
            ny = by - ay;
            edge = (px - ax) * ny + (py - ay) * (-nx);
            if (edge > 0) { return false; }
            nx = cx - bx;
            ny = cy - by;
            edge = (px - bx) * ny + (py - by) * (-nx);
            if (edge > 0) { return false; }
            nx = dx - cx;
            ny = dy - cy;
            edge = (px - cx) * ny + (py - cy) * (-nx);
            if (edge > 0) { return false; }
            nx = ax - dx;
            ny = ay - dy;
            edge = (px - dx) * ny + (py - dy) * (-nx);
            if (edge > 0) { return false; }
            return true;
        }
It works great, maybe not as efficient as it could be but I can't complain.
 
Last edited:
Status
Not open for further replies.
Top