• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

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

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 65
Joined
Aug 10, 2018
Messages
6,660
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:

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,560
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 65
Joined
Aug 10, 2018
Messages
6,660
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