Evenly spaced points on boundary of polygon

I have a polygon and I would like to generate $n$ evenly spaced points along the boundary.

• Welcome! If you have already tried, please share your attempt with us, and it will be easier for us to help – Johu Aug 30 '18 at 21:07

You can use piecewise linear interpolation:

Let's generate a random polygon:

R = ConvexHullMesh[RandomPoint[Disk[], 100]]
polygon = Append[#, #[]] &@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 away Sep 28 '18 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 '18 at 15:11
• Indeed, for applications that need piecewise-linear functions, chord length is still the simplest and best. – J. M. is away Sep 28 '18 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:

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[{
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:

SeedRandom
pts = RandomReal[{-1, 1}, {7, 2}];
coords = pts[[FindShortestTour[pts][]]];
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}] 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: