Skip to content

Instantly share code, notes, and snippets.

@suddhu
Created November 20, 2019 18:43
Show Gist options
  • Select an option

  • Save suddhu/1fe82beb70957332f488755b089c0b01 to your computer and use it in GitHub Desktop.

Select an option

Save suddhu/1fe82beb70957332f488755b089c0b01 to your computer and use it in GitHub Desktop.
Python script that optimizes an input 2D point set to a regular n-sided polygon
#!/usr/bin/env python
# Sudharshan Suresh, Wei Dong, Nov 2019
# Given input ordered point set, regularize the polygon
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')
# regularization loss function
def Regularizer(vertices):
# input: 2 x n
n = vertices.size(1)
centroid = torch.mean(vertices, dim=1).unsqueeze(1)
v = vertices - centroid
loss = 0
# loop through pairwise vertices
for i in range(0, n):
vi = v[:, i]
vip1 = v[:, (i + 1) % n]
val = (vi.T @ vip1) / (vi.norm() * vip1.norm())
# compute angle and loss
anglei = torch.acos(val)
loss += (anglei - 2 * np.pi / n)**2
# print(np.rad2deg(anglei.detach().numpy()), end =" ")
return loss
# take user input ordered vertices (convex shape)
def getPoints():
plt.plot()
plt.title("Shape regularization")
plt.axis('equal')
plt.xlim(-5, 5)
plt.ylim(-5, 5)
print("Make convex shape")
return plt.ginput(0,0)
if __name__ == '__main__':
vertices = nn.Parameter(torch.tensor(getPoints()).t() )
n = vertices.size(1)
# adam optimizer
optimizer = torch.optim.Adam([vertices], lr=0.1)
loss = np.inf
iter = 0
while loss > 1e-7:
iter = iter + 1
plt.cla()
# optimization
loss = Regularizer(vertices)
print('iter: {}, loss: {}'.format(iter, loss))
optimizer.zero_grad()
loss.backward()
optimizer.step()
# plot current iteration
v = vertices.detach().numpy()
plt.scatter(v[0, :], v[1, :])
for i in range(0, n):
plt.plot([v[0, i], v[0, (i+1) % n]], [v[1, i], v[1, (i+1) % n]], 'r--')
# display
plt.axis('equal')
plt.xlim(-5, 5)
plt.ylim(-5, 5)
plt.show(block = False)
plt.pause(0.0001)
plt.show(block = True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment