Hello, I would like to pick a random point in each generation to form a box. However, if I change the slide in grasshopper, it seems to recalculate the whole generation rather than to add a new one upon the previous generation. (see gif1) And if I use seed to control the randon index, the result doesn’t seem “so random” (see gif2). Is there any solution to add new iteration on the previous one?
Thanks!
my code:
addedPoints = []
for i in range(iteration):
random.seed(40)
index = random.randint(0, (len(a)-1))
selectedPoint = a[index]
a.remove(selectedPoint)
addedPoints.append(selectedPoint)
i = addedPoints
a.remove just modifies the Python list (a), it doesn’t change anything in the underlying Rhino file.
I don’t know if RhinoPython scripts can store state between executions. If they can access sc.sticky you could create a new entry in it and store a set of previously boxed points there.
If you intend to modify the document, then inside the RhinoDoc I would either add a label to a point when it gets boxed or move them to a special layer.
In a GhPython component, the list boxed components can easily be stored in a component class’s instance variable in SDK mode.
Then which ever method you use, simply add a check to make sure the code doesn’t box a point that’s already been boxed, or use:
selectedPoint = random.choice([point for point in a if point not in boxed_points])
Hi James, thank you for answering! And thank you for the suggestion on random.choice.
However, I don’t know if I understand your words right on the storing data part. My codes look like this now but it still doesn’t store the previous boxed points. Does it store the boxed points in the class’s instance variable as you said or I wrote something wrong?
class Principles:
def __init__(self, _matrix):
self.matrix = _matrix
def add (self, _addedPoints):
self.ePts = _addedPoints
selectedPoint = random.choice([point for point in self.matrix if point not in self.ePts])
return selectedPoint
principles = Principles(a)
addedPoints = []
for i in range(iteration):
selectedPoint = principles.add(addedPoints)
addedPoints.append(selectedPoint)
i = addedPoints
Firstly you need to open grasshopper, place a GhPython component, make sure there’re exactly two input Params and exactly one output Param (not called output), change the first input and the output to list mode, double click the component, change it into SDK mode using the pull down menu at the top of its editor, and paste in the code below over everything:
import random
from ghpythonlib.componentbase import executingcomponent as component
class MyComponent(component):
def __init__(self):
self.boxedPoints = set()
def RunScript(self, a, iteration):
addedPoints = []
for i in range(iteration):
selectedPoint = random.choice([point for point in a if point not in self.boxedPoints])
self.boxedPoints.add(selectedPoint)
addedPoints.append(selectedPoint)
return addedPoints
Thank you James for your support! However, it still resets everytime I change the iteration.
But I find that if I move random.seed outside the for loop, the problem seems to be solved. I think the result before caused by the changing seed everytime the loop starts.
But anyway I really appreciate your help! random.choice is quite useful and I learnt a lot about .sticky. Thanks!