I've a polygon like this:
The vertices are ordered correctly (anti-clockwise, I think):
coords = [
{x: 428.0, y: 273.0}, {x: 410.0, y: 335.0}, {x: 398.0, y: 350.0}, {x: 384.0, y: 355.0}, {x: 363.0, y: 410.0},
{x: 354.0, y: 424.0}, {x: 318.0, y: 455.0}, {x: 299.0, y: 458.0}, {x: 284.0, y: 464.0}, {x: 250.0, y: 490.0},
{x: 229.0, y: 492.0}, {x: 204.0, y: 484.0}, {x: 187.0, y: 469.0}, {x: 176.0, y: 449.0}, {x: 164.0, y: 435.0},
{x: 144.0, y: 392.0}, {x: 132.0, y: 349.0}, {x: 122.0, y: 334.0}, {x: 120.0, y: 324.0}, {x: 121.0, y: 294.0},
{x: 119.0, y: 274.0}, {x: 121.0, y: 264.0}, {x: 118.0, y: 249.0}, {x: 118.0, y: 224.0}, {x: 121.0, y: 209.0},
{x: 130.0, y: 194.0}, {x: 138.0, y: 159.0}, {x: 147.0, y: 139.0}, {x: 155.0, y: 112.0}, {x: 170.0, y: 89.0},
{x: 190.0, y: 67.0}, {x: 220.0, y: 54.0}, {x: 280.0, y: 47.0}, {x: 310.0, y: 55.0}, {x: 330.0, y: 56.0},
{x: 345.0, y: 60.0}, {x: 355.0, y: 67.0}, {x: 367.0, y: 80.0}, {x: 375.0, y: 84.0}, {x: 382.0, y: 95.0},
{x: 395.0, y: 106.0}, {x: 403.0, y: 120.0}, {x: 410.0, y: 151.0}, {x: 417.0, y: 210.0}, {x: 419.0, y: 215.0},
{x: 425.0, y: 218.0}, {x: 431.0, y: 225.0}, {x: 430.0, y: 265.0},
]
I would like to resample those vertices to space them evenly. It could be probably done by re-interpolating the 2D vertices but that's not something I'm confortable with and I wonder if a library already does that before trying to reinvent the wheel. How could I do?
For example, with n=15
, I get a set of coordinates which looks like this:
With @kaya3 solution, n=128
:
Here's a possible solution: choose k
evenly spaced points by dividing the total perimeter of the polygon by k
, and linearly interpolating.
import math
def distance(p, q):
return math.hypot(q['x'] - p['x'], q['y'] - p['y'])
def lerp(p, q, t):
return {
'x': (1 - t) * p['x'] + t * q['x'],
'y': (1 - t) * p['y'] + t * q['y']
}
def resample_polygon(polygon, k):
edges = list(zip(polygon, polygon[1:] + polygon[:1]))
arc_length = sum(distance(p, q) for p, q in edges) / k
result = [polygon[0]]
t = 0
for p, q in edges:
d_t = distance(p, q) / arc_length
while t + d_t >= len(result) < k:
v = lerp(p, q, (len(result) - t) / d_t)
result.append(v)
t += d_t
return result