0
$\begingroup$

I am trying to create a simple (with no self-intersections) polygon having four given points as vertices, for example to calculate its perimeter later. However, it seems there is nothing for this basic functionality. For instance, I would like to create a square given the following sequence of four points (irrespective to their order) in the following example, but I cannot "force" the software to create a simple polygon:

Polygon[{{0,0},{1,1},{1,0},{0,1}}]

I would like that the software to "arrange" the sequence of points to create a simple polygon, that is, in this specific case, a square (WindingPolygon does not work for this purpose).

$\endgroup$
1
  • $\begingroup$ You might be interested in CirclePoints as well to generate the vertices of a regular polygon. $\endgroup$
    – MarcoB
    Nov 18, 2020 at 17:35

4 Answers 4

8
$\begingroup$

If you already have the list of coordinates, then FindCurvePath should be able to re-order them for you:

pts = {{0, 0}, {1, 1}, {1, 0}, {0, 1}};
Graphics@ Polygon[pts]

not simple

Graphics@Polygon@pts[[First@FindCurvePath[pts]]]

simple polygon output

$\endgroup$
3
  • $\begingroup$ Thank you very much. It works for plotting the simple polygon, but I do not understand why it does not work in this simple optimization problem, where we look for the simple 4-gon with maximal perimeter in the region of the unit disc: NMaximize[{Perimeter[Polygon[{{a, b}, {c, d}, {e, f}, {g, h}}[[First[FindCurvePath[{{a, b}, {c, d}, {e, f}, {g, h}}]]]]]], a^2+b^2<=1, c^2+d^2<=1, e^2+f^2<=1, g^2+h^2<=1}, {a,b,c,d,e,f,g,h}] . How can we arrange the NMaximize command argument in your opinion? $\endgroup$ Nov 18, 2020 at 20:25
  • 1
    $\begingroup$ @PenelopeBenenati I don't think FindCurvePath would have any way of working symbolically; I think you might want to hide it behind a target function perhaps, with inputs protected by ?NumericQ. $\endgroup$
    – MarcoB
    Nov 18, 2020 at 21:00
  • $\begingroup$ Could you please provide me an example of he use of "?NumericQ" within this specific context (maximizing the perimeter of a simple polygon within a certain region of the plane)? Thank you in advance! PS: I am open to completely alternative solution for formalizing this problem. $\endgroup$ Nov 19, 2020 at 0:18
3
$\begingroup$

You just need to sort your points according to an increase of the bypass angle.

Graphics@Polygon[
  SortBy[
{{0, 0}, {1, 1}, {1, 0}, {0, 1}}, 
   Arg[First@# + I Last@#] &
]]

Actually, the sorting function can be different just keep the bypass angle increasing...

$\endgroup$
2
  • 1
    $\begingroup$ I think I know what you mean, but I'm not familiar with the term "bypass angle". Can you add a link perhaps? $\endgroup$
    – MarcoB
    Nov 18, 2020 at 17:50
  • $\begingroup$ @MarcoB, May be I've used the wrong English term. I mean that if you have the set of points, than you can draw the convex polygon by paving the path from one point to another only if the set is ordered by the special way. The main requirement for points sorting is permanent increase (or decrease) of the winding angle of vector connecting the center of the figure and these points. $\endgroup$
    – Rom38
    Nov 19, 2020 at 7:34
2
$\begingroup$

Toward the problem in the comment.

For arbitrary 4 points in Disk[],the 4 points not always construct a simple region.

SeedRandom[9876543]
pts = RandomPoint[Disk[],4]; 

{{Graphics[{Point[pts], Circle[], Orange, Opacity[0.5], 
     Polygon[pts]}], 
   Perimeter[
    Polygon[pts]]}, {Graphics[{Point[pts], Circle[], Orange, 
     Opacity[0.5], DelaunayMesh[pts]}], 
   Perimeter[DelaunayMesh[pts]]}} // Grid

enter image description here

Although the NMaximize Area problem is easy to do, the Perimeter problem is still not easy to handle.

sol = NMaximize[{Area[Polygon[{x, y, z, w}]], 
    x ∈ Disk[] && y ∈ Disk[] && 
     z ∈ Disk[] && w ∈ Disk[]}, {x, y, z, w}];
pts = {x, y, z, w} /. Last@sol;
Graphics[{Brown, Polygon[pts], FaceForm[], EdgeForm[Cyan], Disk[]}]

enter image description here

NMaximize[{Perimeter[Polygon[{x, y, z, w}]], 
  x ∈ Disk[] && y ∈ Disk[] && z ∈ Disk[] && 
   w ∈ Disk[]}, {x, y, z, w}]
$\endgroup$
0
$\begingroup$
vertices[n_] := Table[{Cos[(2 \[Pi] k)/n], Sin[(2 \[Pi] k)/n]}, {k, Range[0, n]}];
polygon[n_] := Graphics@Line[vertices[n]];

GraphicsRow[Table[polygon[n], {n, Range[3, 7]}]]

enter image description here

Also, if you want your squares square, and your polygons black:

vertices2[n_] := 
  Table[{Cos[(2 \[Pi] ( k - 1/2))/n], Sin[(2 \[Pi] (k - 1/2))/n]}, {k,
     Range[0, n]}];

GraphicsRow[Table[Graphics[Polygon@vertices2[n]], {n, Range[3, 7]}]]

enter image description here

$\endgroup$
2
  • $\begingroup$ You may care to add that the built-in CirclePoints does the same thing; you can set starting angle as well. $\endgroup$
    – MarcoB
    Nov 18, 2020 at 17:49
  • $\begingroup$ Yes, you are right! Why reinvent the wheel?! $\endgroup$
    – mjw
    Nov 18, 2020 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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