I'm tired of typing and deciphering coordinates of the corners rectangles, and I'm wondering if anyone has found a better way.

A rectangle can simply be described by two lists x = {x1, y1} and y = {x2, y2}, but the coordinates of the corners quickly becomes the jumble {{x1, y1}, {x1, y2}, {x2, y2}, {x2, y1}} (if the coordinates are listed clockwise). It gets worse for cubes and higher dimensions.

I've found one promising approach. This is to create two lists for the points on the different axes, x = {x1, x1, x2, x2} and y = {y1, y2, y2, y1}, and then combine them with Transpose@Join[{x},{y}]. This approach extends to higher dimensions and also works for polygons, but it still requires the manual duplication of values.

One could write a function to do this in a black box, but I wonder if there a way to do elegantly and intuitively convert pairs of ranges into coordinates for rectangles?

  • 1
    $\begingroup$ Tangentially related, but you may also want to look at this family of functions like CoordinateBounds and CoordinateBoundingBox: reference.wolfram.com/language/guide/… $\endgroup$
    – flinty
    Jun 15 '20 at 12:54

An alternative, and to get them in clock wise order, is to use Outer product, something like

canonicalizePolygon[{x1_, y1_}, {x2_, y2_}] := Module[{coord},
   coord = Outer[List, {x1, x2}, {y1, y2}];
   coord[[2]] = Reverse[coord[[2]]];
   Flatten[coord, 1]

Call it as

canonicalizePolygon[{x1, y1}, {x2, y2}]

enter image description here

For a cubiod, same thing, find coordinates of corners for the front face rectangle, and then find coordinates of corners for the back face rectangle.

For other shapes, I think it will have to be case by case.


Perhaps I didn't get the purpose of your question/application…

The function CanonicalizePolygon helps to find the 4 points of Rectangle[{x1,y1},{x2,y2}]

CanonicalizePolygon[Rectangle[ {x1, y1}, {x2, y2} ]][[ 1]] 
(*{{x1, y1}, {x1, y2}, {x2, y1}, {x2, y2}}*)  

or with assumptions

CanonicalizePolygon[Rectangle[ {x1, y1}, {x2, y2} ],Assumptions -> {x2 > x1, y2 > y1  }][[ 1]]   
(*{{x1, y1}, {x2, y1}, {x2, y2}, {x1, y2}}*)
  • $\begingroup$ Thank you, this is a useful function to know. $\endgroup$
    – Niel Malan
    Jun 16 '20 at 13:07
n = 2;
Tuples@Array[x, {n, 2}]

{{x[1, 1], x[2, 1]}, {x[1, 1], x[2, 2]}, {x[1, 2], x[2, 1]}, {x[1, 2], x[2, 2]}}


n = 3;
Tuples@Array[x, {n, 2}]

{{x[1, 1], x[2, 1], x[3, 1]}, {x[1, 1], x[2, 1], x[3, 2]}, {x[1, 1], x[2, 2], x[3, 1]}, {x[1, 1], x[2, 2], x[3, 2]}, {x[1, 2], x[2, 1], x[3, 1]}, {x[1, 2], x[2, 1], x[3, 2]}, {x[1, 2], x[2, 2], x[3, 1]}, {x[1, 2], x[2, 2], x[3, 2]}}


x = {x1, y1};
y = {x2, y2};
z = {x3, y3};
Tuples[{x, y, z}]

{{x1, x2, x3}, {x1, x2, y3}, {x1, y2, x3}, {x1, y2, y3}, {y1, x2, x3}, {y1, x2, y3}, {y1, y2, x3}, {y1, y2, y3}}

  • $\begingroup$ Straightforward solution! Perhaps Transpose missing?: Tuples@Transpose[{{x1, y1}, {x2, y2}}] $\endgroup$ Jun 15 '20 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.