I have a set of points with x and y coordinates that can be seen in the figure below. The coordinates of the 9 points were stored in a list as follows:
L = [[5,2
this should illustrate the issues, gives a visualization tool
but it doesn't work every time for the getting the correct entry point for a group of points at the same distance
import random
import pylab
import cmath
from itertools import groupby
pts = [(random.randrange(-5,5), random.randrange(-5,5)) for _ in range(10)]
# for this problem complex numbers are just too good to pass up
z_pts = [ i[0] + 1j*i[1] for i in pts if i != (0, 0)]
z_pts.sort(key = lambda x: abs(x))
gpts = [[*g] for _, g in groupby(z_pts, key = lambda x: abs(x) ) ]
print(*gpts, sep='\n')
spts = [1j/2]
for e in gpts:
if len(e) > 1:
se = sorted(e, key = lambda x: cmath.phase(-x / spts[-1]))
spts += se
else:
spts += e
print(spts)
def XsYs(zs):
xs = [z.real for z in zs]
ys = [z.imag for z in zs]
return xs, ys
def SpiralSeg(a, b):
'''
construct a clockwise spiral segment connecting
ordered points a, b specified as complex numbers
Inputs
a, b complex numbers
Output
list of complex numbers
'''
seg = [a]
if a == 0 or a == b:
return seg
# rotation interpolation with complex numbers!
rot = ( b / a ) ** ( 1 / 30 )
# impose cw rotation direction constraint
if cmath.phase( b / a ) > 0: # add a halfway point to force long way around
plr = cmath.polar( b / a )
plr = (plr[0]**(1/2), plr[1] / 2 - 1 * cmath.pi ) # the rotor/2
a_b = cmath.rect(*plr) * a # rotate the start point halfway round
return SpiralSeg(a, a_b) + (SpiralSeg(a_b, b))
for _ in range(30):
a *= rot
seg.append(a)
return seg
segs = [SpiralSeg(a, b) for a, b in zip(spts, spts[1:])]
pylab.axes().set_aspect('equal', 'datalim')
pylab.scatter(*XsYs(z_pts))
for seg in segs:
pylab.plot(*XsYs(seg))
[(1-2j), (-2-1j)]
[(2-3j)]
[(1+4j)]
[(3+3j)]
[(-3-4j), (3-4j), (4-3j)]
[(1-5j)]
[(-4-4j)]
[0.5j, (-2-1j), (1-2j), (2-3j), (1+4j), (3+3j), (-3-4j), (3-4j), (4-3j), (1-5j), (-4-4j)]

[-1j]
[(-1-1j)]
[(-1-2j), (-1+2j), (2+1j)]
[(-4+0j)]
[(1-4j)]
[-5j, (-4-3j)]
[(1-5j)]
[0.5j, -1j, (-1-1j), (-1-2j), (2+1j), (-1+2j), (-4+0j), (1-4j), (-4-3j), -5j, (1-5j)]