# 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, 2018 at 21:07

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... Sep 28, 2018 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. Sep 28, 2018 at 15:11
• Indeed, for applications that need piecewise-linear functions, chord length is still the simplest and best. Sep 28, 2018 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[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: