Hello everyone, I have been trying to figure this problem for some time but I can not seem to find a solution that works for all cases.
I have a list of 4 points in Dynamo that form a (polygon) quadrilateral. I want to know which one is the most top-right point, top-left point, bottom-right point, and bottom-left point. I have been working on this with python.
I have tried several approaches that work is some cases but not in others. Firstly I tried tried using the centroid of the respective polygon and based on each pointâs X and Y coordinate figure out in which corner it is. This approach worked well for rectangles but once I have a higher parallelogram (in Y axis) the centroid is no longer perpendicular to the sides which creates issues.
I have tried ordering the points based on the angle they form with the centroid and with the help of an atan2 function order them in a counter-clockwise manner and with that get their respective position, with the first point always being the bottom-left one. This worked for most of the cases but with longer (and slender) shapes the atan2 approach still orders them counter-clockwise but the starting point is different, which again creates problems. Im not sure if there is a way to make the sorting always begin at the same point. This is what I have tried:
That should work. The only edge case youâd have to deal with is when the two left and right corners have the same Y coordinate (or X coordinate for top and bottom), but thatâs fairly straightforward.
Hi Alien, thank you very much for the suggestion. I will try it out, but if I understood correctly, im not sure if it will work because if both highest X values are in the bottom side then I will get the points in the bottom side instead of the right side. I guess the polygon from the picture also would give the same output, but in this case the two highest X values are both in the topside.
You need to sort the top/bottom first. These quadrants are relative to the shape so top-right and right-top may not always be the same. It depends on how you sort first.
A quadrant can contain 0, 1, or more than one points. This means that identifying a point goes beyond just identifying the quadrant. The order in which you prioritize coordinates can make a difference relative to the shapeâs up-down and left-right directionalities. If you sort by Y coordinates first, you get the outer identities. If you sort by X first, you get the inner identities. This effectively changes the top right quadrant from being the âtopâ of the shape for Y prioritization to the ârightâ of the shape for the X prioritization. The continuity of the points stays the same, i.e. TL > TR > BR > BL in a clockwise fashion, even though the identifiers have changed.
All of that is to say that âtop-leftâ or âbottom-rightâ are both relative and somewhat arbitrary. So donât worry about the âcorrectâ answer so much and instead focus on getting consistent and accurate results from your edge cases. All of the suggestions given so far can do that.
Hello Jacob, thank you very much for the suggestion, yes the points are planar. I have tried it on a couple of different shapes (without the 5th point) and in general it works great, the resulting sorted list always starts with the top-left point and from there I can assign the orientation to the rest as they are always in clockwise order. However, there is one case (which is the actual case I need it to work for) where the respective x and y point coordinates are substantially high (>100000000 units) and there the ordered list starts from the top-right point. I assume the 5th point of your suggestion is to address such situations but Iâm not particularly sure how to implement it since in many of the cases I tried the first of the sorted degrees is greater than 45 degrees. Would in this case the atan2 function solve this issue since it will also return the sign of the angles?
Hello Nick, thank you very much for the insightful comment. I have stumbled upon this issue when trying out a shape similar to the one you showed, and the naming indeed is always relative to something arbitrary. The main goal that I want to achieve is to eventually have a surface for which I can identify the corners with the North-South-East-West directions. In this case the top-right would be the North-East corner and so on. Therefore, identifying either of the corners consistently across all cases would allow me to identify all the rest.
Probably both, I assume I would never come across such a shape, and therefore need to constrain the cases in which what Iâm trying to achieve must work. Thanks.
Right - and this is sort of what Iâm getting at. You started to get there with âfour pointsâ, but perhaps itâs more 'four points and no angles over X degrees or under Y degrees? The mroe of these constraints you put in place the easier it is to build a functional setup.
Even with that youâre also going to have a LOT of edge cases (the joy of geometry is that you donât know what youâve got until you have it). We covered one with the 45 degree angle, but another would be matching angles.
All of that said⌠Hearing that youâre after finding the ânorth, east, south, and westâ edges, and you only have 4 edges, then why not work with the edges instead?
Ensure the polygon is clockwise in nature
Pull the curves
Get the normal of each line
Get the angle from the normal to the Y axis
Get the index of the minimum angle
Shift the list of curves by the inverse of the index (multiply the index by -1)
The first curve is the north edge. The second curve east edge, the third curve south edge, and the final curve is the west edge.
The specifics assignment for any edge might not make sense if any of the angles are too great or small, but generally speaking itâll do well for you.
Hi Jacob, first of all thank you for the help and suggestions. I have tried your last suggestion and it worked well, and indeed applying constrains did solve the issues, after all there are infinitely many shapes you can get with 4 points so making 1 script that can work for all is impossible.