Evenly spaced points on boundary of polygon
Evenly spaced points on boundary of polygon
I have a polygon and I would like to generate $n$ evenly spaced points along the boundary.
5 Answers
5
You can use piecewise linear interpolation:
Let's generate a random polygon:
R = ConvexHullMesh[RandomPoint[Disk, 100]]
polygon = Append[#, #[[1]]] &@MeshCoordinates[R][[MeshCells[R, 2][[1, 1]]]];
Creating a piecewise-linear interpolation which is parameterized by arc length.
t = Prepend[Accumulate[Norm /@ Differences[polygon]], 0.];
γ = Interpolation[Transpose[t, polygon],
InterpolationOrder -> 1,
PeriodicInterpolation -> True
];
Sampling it uniformly:
s = Subdivide[γ[[1, 1, 1]], γ[[1, 1, 2]], 100];
newpts = γ[s];
And plotting the generated points:
Show[
R,
ListPlot[newpts]
]
Ah, chord-length parametrization. Sometimes I use it for splines...
– J. M. is computer-less♦
Sep 28 at 15:01
@J.M. Yes, and I also used your implementation frequently, e.g. to obtain smooth approximations to polygonal knots (application is e.g. mesh creation for Plateau problems). But here we want to follow the polygon exactly, so smoothing is actually unwanted.
– Henrik Schumacher
Sep 28 at 15:11
Indeed, for applications that need piecewise-linear functions, chord length is still the simplest and best.
– J. M. is computer-less♦
Sep 28 at 15:14
If you just want to generate a graphic, then you could use an Arrow
with a custom Arrowheads
directive. For example, here is a Polygon
object:
Arrow
Arrowheads
Polygon
poly = Polygon[
7.361093855790543, 0.2777667989114292, 8.37955832193947, 4.837661706721057,
8.064449639390588, 8.016729782194783, 3.518023168010062, 8.74578450698846,
0.8343834304870779, 2.2170380309534554, 4.807772222882807, 0.09815872747936005,
7.361093855790543, 0.2777667989114292
];
Graphics[RegionBoundary @ poly]
Show 10 evenly spaced points:
Graphics[
Arrowheads @ Append[
ConstantArray[
.1, Automatic, Graphics[PointSize[Large], Point[0,0]],
10
],
0
],
Arrow @@ RegionBoundary[poly]
]
You can use BSplineFunction
and ParametricPlot
with ArcLength
as option value for the option MeshFunctions
:
BSplineFunction
ParametricPlot
ArcLength
MeshFunctions
SeedRandom[77]
pts = RandomReal[-1, 1, 7, 2];
coords = pts[[FindShortestTour[pts][[2]]]];
n = 10;
bsF = BSplineFunction[coords, SplineDegree -> 1];
ParametricPlot[bsF[t], t, 0, 1, Frame -> True, Axes -> False, AspectRatio -> Automatic,
MeshFunctions -> ArcLength,
Mesh -> n,
MeshStyle -> Directive[Red, PointSize[Large]],
Epilog -> Red, PointSize[Large] , Point@bsF[0]]
We could also use mesh functions, as Vitaliy showed here:
plot = ListLinePlot[
coords,
Mesh -> 20,
MeshFunctions -> "ArcLength"
];
pts = Cases[Normal[plot], Point[pt_] :> pt, Infinity];
pts = Prepend[pts, First[coords]];
Graphics[
Line[coords],
PointSize[Large], Red, Point[pts]
]
I reused the polygon in Carl's answer.
I think that the broad scheme of doing it would be as follows:
Load the Polytopes package:
<< Polytopes`
Use the vertices command (e.g. assuming that you are working with an octagon):
a=Vertices[Octagon]
Set up a function which interpolates between two points using a parameter t.
Use the Map command to calculate the interpolated co-ordinates for any given value of t on successive values of your vertices.
Thanks for contributing an answer to Mathematica Stack Exchange!
But avoid …
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Welcome! If you have already tried, please share your attempt with us, and it will be easier for us to help
– Johu
Aug 30 at 21:07