Find top-right, top-left, bottom-right, bottom-left in a list of 4 points forming different quadrilateral shapes

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:

First thought…

If you get max and min X and Y …

then put the two highest X into one group and the two highest Y into another group…
Then the first group is right, second group is left hand side.

Then in the first group, get the highest Y and this is top right. etc.

Does that not work?

EDIT… just thought of a scenario where this does not work… :expressionless:
EDIT again… actually… does it not work? :person_shrugging:

1 Like

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.

1 Like

Can you give examples?

I’ve been thinking of fun ways of doing this…

How about…

Draw a bounding box (red) round the 4 sided shape…

TL = Top Left,
BR = Bottom Right

Then find the nearest two points to TL and TR… this point is then labelled R
Repeat for the other 3 points.

If an item is in both R groups it gets an R, if it’s in both T groups it gets a T…

Then put R and L items into a group and see which has the lowest Y value… That point then gets a B (so it’s either BR or BL) …

Then the other one of that group gets a T (so either TR or TL)

Repeat the process with the T and B.

If you get two items in the top then you see which has got the lowest X for left…

Bit contrived maybe… but dunno… kinda fun :smiley:

image

2 Likes

Question: are the points planar?

  1. Get the average point.
  2. Get the vector from the average point to each of the points.
  3. Get the angle from that location to the negative X axis about the negative Z axis.
  4. Sort the points using the angles as a key.
  5. If the first of the sorted degrees is greater than 45 degrees shift the points list by one.
2 Likes

Hopefully this diagram isn’t too confusing and helps explain the issue.

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.

1 Like

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?



Angles with atan2

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.

Sounds like you’re either asking the wrong question, or that you aren’t constraining your options well. Take a four sided shape like this:

Which face is north?

1 Like

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?

  1. Ensure the polygon is clockwise in nature
  2. Pull the curves
  3. Get the normal of each line
  4. Get the angle from the normal to the Y axis
  5. Get the index of the minimum angle
  6. 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.

4 Likes

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.

1 Like