I have a list of vertices.
I want to move the verts/white squares along their own paths like so:

(Assume the polygon is closed)
How can I do that with python and get a list of shifted vertices back?
I have a list of vertices.
I want to move the verts/white squares along their own paths like so:

(Assume the polygon is closed)
How can I do that with python and get a list of shifted vertices back?
Here is the solution I ended up using. Suggestions welcome.
import bpy
import numpy as np
#assumes closed polygon with vertices in linear order
#creates new objetc with shifted/slid verts
#https://blender.stackexchange.com/questions/191649/how-can-i-sort-vertex-positions-sequentially-indices-in-a-closed-area
def multi_slide_verts(obj, shift_length):
def read_verts(obj):
length = len(obj.data.vertices)
coords = np.empty(length*3, dtype=np.float64)
obj.data.vertices.foreach_get('co',coords)
coords.shape = (length, 3)
return coords #numpy array of vert array [[x,y,z],[x,y,z]...]
def write_obj_from_pydata(name, verts, edges=None, close=True):
if edges is None:
# join vertices into one uninterrupted chain of edges.
edges = [[i, i+1] for i in range(len(verts)-1)]
if close:
edges.append([len(verts)-1, 0]) #connect last to first
me = bpy.data.meshes.new(name)
me.from_pydata(verts, edges, [])
obj = bpy.data.objects.new(name, me)
bpy.context.scene.collection.objects.link(obj)
#collect segments, their length and directions in parallel numpy arrays
P1 = read_verts(obj) #all verts
P2 = np.roll(P1, -1, axis=0)
segs = P2-P1
dists = np.linalg.norm(P2-P1, axis=1)+0.000000001
dirs = segs/dists[:, np.newaxis] #.np.new axis to give same shape, https://stackoverflow.com/questions/7140738/numpy-divide-along-axis
shifted_pts = []
for i in range(len(P1)):#iterate over all points
#normal/easiest case, shift point on own segment in segment direction
if dists[i]>=shift_length:#dist is big enough
copy_original_pt = P1[i][:]
shifted_pt = copy_original_pt+(dirs[i]*shift_length)
shifted_pts.append(shifted_pt)
#case where you need to look beyond neighbouring verts for shifting direction/dist
else: #dist is not enough to apply shift, so you need to lookahead and see if next seg dist is enough.
traveled_dist = dists[i]
lookahead = 0 #number of segments to skip to have enough for shift length
while traveled_dist < shift:
#check if next segment is enough and note down traveled_dist
lookahead+=1
#to make lookahead indices stay in range when looking further than last point
rotate_index = (i+lookahead)%len(dists) #rotate i lookahead goes further then last point, cause for now your path is cyclic!
traveled_dist+=dists[rotate_index]
#same for distance to calculate rest amount you didn't travel yet.
shift_rest = shift - (traveled_dist-dists[rotate_index])
copy_original_pt = P1[rotate_index][:]
shifted_pt = copy_original_pt+(dirs[rotate_index]*shift_rest)
shifted_pts.append(shifted_pt)
write_obj_from_pydata('shifted_pts', shifted_pts, edges=None, close=True)
obj = bpy.context.active_object
multi_slide_verts(obj, 9.3)