Shifting a list


#1

Hello,

I am struggling with shifting a list inside a class.

I made a random walker path with a list a lines. Now I would like to connect each of these lines, two by two, by dividing them by a number of points and linking them with these same points (pt1 to pt1, pt2 to pt2, etc.)
You can see what I am trying to achieve with the picture below (I made it with grasshopper)

Basically, I wanted to create two lists of lines, one of them shifted by one.
Then it is easy to connect the first point to the first point, the second to the second one, etc.
I tried to shift the list with the function .pop(0) but it doesn’t work.

Here is the code :


import rhinoscriptsyntax as rs
import random as r
r.seed(5)

time = 50

class Walker:
    
    def __init__(self):
        self.x = 50
        self.y = 50
        self.z = 0
        rs.AddPoint(self.x,self.y,self.z)
        sph1 = rs.AddSphere((self.x, self.y, self.z),0.1)
        
    def point(self):
        self.shape1 = (self.x, self.y, self.z)
        
        
    def step(self):
        stepX = r.uniform(-1,1)
        stepY = r.uniform(-1,1)
        stepZ = r.uniform(-1,1)
        
        self.x += stepX
        self.y += stepY
        self.z += stepZ
        self.shape2 = rs.AddPoint(self.x, self.y, self.z)
        sph2 = rs.AddSphere(self.shape2,0.1)
        
        
        
    def lines(self):
        self.line1 = rs.AddLine(self.shape1, self.shape2)
        self.line2 = rs.AddLine(self.shape1, self.shape2)

    def divLines(self):
        self.divPts1 = rs.DivideCurve(self.line1,5,True,True)
        self.divPts2 = rs.DivideCurve(self.line2,5,True,True)
        self.divPts2.pop(0)


    def linkPts(self):
        self.lineBetPts = rs.AddLine(self.divPts1[0], self.divPts2[3])


w = Walker()

pList = []
for t in range(time): 
    pList.append(w.point())
    w.step()
    pList.append(w.lines())
    pList.append(w.divLines())
    pList.append(w.linkPts())

As you can see, it the def linkPts(self) definition, I wrote “rs.AddLine(self.divPts1[0], self.divPts2[3])”.
Normally I would like to connect all of the points from each list, so "rs.AddLine(self.divPts1, self.divPts2)"
But I didn’t wrote it yet because it doesn’t work for the moment (the points are overlapping).

Any idea?

Thank you,

Paul


#2

.pop(0) removes the first point in that list, so the second list will simply have one less point, and will begin at the second point.

if you want to shift all the items towards the beginning of the list, and you want that shift to “wrap” (making the first item into the last item), you should replace

self.divPts2.pop(0)

with

self.divPts2.append( self.divPts2.pop(0) )

to shift in the opposite direction, you would do:

self.divPts2.insert(0,  self.divPts2.pop() )

to connect all the lines

for i, pt1 in enumerate(self.divPts1):
    j = i + 1
    if j == len(self.divPts2):
        j = 0
    pt2 = self.divPts2[j]
    rs.AddLine(pt1, pt2)

#3

Hello bengolder,

Thank you for your reply.

I understood what you said. However, I made a mistake: I didn’t want to shift the points in my code, but the list of the lines.
Because the points are grafted on each line, so there is [0, 1, 2, 3, 4, 5] items for each lines. If I shift one of them and then I link them, they will simply overlapp each other.

Anyway, I applied your method for the lines.

self.line2.append( self.line2.pop(0) )

But here there is a problem : "Message: ‘Guid’ object has no attribute ‘append’.

Code :

import rhinoscriptsyntax as rs
import random as r
r.seed(5)

time = 50

class Walker:
    
    def __init__(self):
        self.x = 50
        self.y = 50
        self.z = 0
        rs.AddPoint(self.x,self.y,self.z)
        sph1 = rs.AddSphere((self.x, self.y, self.z),0.1)
        
    def point(self):
        self.shape1 = (self.x, self.y, self.z)
        
    def step(self):
        stepX = r.uniform(-1,1)
        stepY = r.uniform(-1,1)
        stepZ = r.uniform(-1,1)
        
        self.x += stepX
        self.y += stepY
        self.z += stepZ
        self.shape2 = rs.AddPoint(self.x, self.y, self.z)
        sph2 = rs.AddSphere(self.shape2,0.1)
        
    def lines(self):
        self.line1 = rs.AddLine(self.shape1, self.shape2)
        self.line2 = rs.AddLine(self.shape1, self.shape2)
        self.line2.append( self.line2.pop(0) )

    def divLines(self):
        self.divPts1 = rs.DivideCurve(self.line1,5,True,True)
        self.divPts2 = rs.DivideCurve(self.line2,5,True,True)
        
        
    def linkPts(self):
        self.lineBetPts = rs.AddLine(self.divPts1[0], self.divPts2[3])
        """for i, pt1 in enumerate(self.divPts1):
            j = i + 1
            if j == len(self.divPts2):
                j = 0
            pt2 = self.divPts2[j]
            rs.AddLine(pt1, pt2)"""


w = Walker()

pList = []
for t in range(time): 
    pList.append(w.point())
    w.step()
    pList.append(w.lines())
    pList.append(w.divLines())
    pList.append(w.linkPts())
    #print w.x

Thank you,

Paul