Panel doesn't put squares on it

Hey everyone!

I’m making a ‘creative’ task in RhinoPython
So I tried making this ‘wall’ kind of thing with empty squares of different sizes in it by extruding a panel. The code totally worked fine. Now i wanted to add a sinewave, where all the squares should stay above (but still inside of the panel!). Only problem is that rhino doesn’t want to draw any squares anymore right now. I think the problem is somewhere at the list of zCoors. Although i am quite sure that the given coordinates are right coordinates to draw squares onto.

Thanks for your help!

Marnix

import rhinoscriptsyntax as rs
import random as rd
import math

rs.Command('SelAll')
rs.Command('Delete')

# global variables
panelWidth = 300
panelHeight = 100
iterationNum = 200
radiusMin = 1.5
radiusMax = 8
extrudeHeight=5
minGap = panelHeight/30
gulfSize=10


wavePoints=[]
zCoors=[]
for x in range(0,panelWidth):
    z=3*math.sin(x/5)
    liftedzCoor=z+panelHeight*2/3
    zCoors.append(liftedzCoor) #The zCoors of the squares should be above the wave
    point = (x,0,z)
    gulfPoint = rs.CreatePoint(point)
    wavePoints.append(gulfPoint)

sineWave=rs.AddInterpCurve(wavePoints)
rs.MoveObject(sineWave,(0,0,panelHeight*2/3))

# Step 1: Create a permutation
def MakePolygon(inputSize):
    xCoor = rd.uniform(0,panelWidth) # draw a square with a certain size at a random center inside the panel
    zCoor = rd.uniform(zCoors[int(xCoor)],panelHeight) #making sure the zCoors are actually between the wave and the panelHeight
    randomCenter = rs.CreatePoint(xCoor,0,zCoor)
    print(randomCenter)
    primitiveSquare=rs.AddRectangle(rs.WorldZXPlane(),inputSize,inputSize)
    rotatedSquare=rs.RotateObject(primitiveSquare,randomCenter,45,axis=(0,1,0))
    newSquare=rs.MoveObject(rotatedSquare,randomCenter)
    return newSquare

# Step 2. Check whether this permutation is valid
def TestPolygon(inputPolygon):
    if rs.PlanarClosedCurveContainment(inputPolygon,panel,plane=rs.WorldZXPlane()) == 2: # test if inputPolygon is inside the panel
        testResult=True
        for square in allSquares:
            if rs.PlanarClosedCurveContainment(inputPolygon,square,plane=rs.WorldZXPlane()) != 0 : #test if inputPolygon and square intersect
                testResult=False
                break
    else: testResult=False
    return testResult # return either True or False

def TestPolygon(inputPolygon,inputSize):
    testResult = True
    if rs.PlanarClosedCurveContainment(inputPolygon,panel,plane=rs.WorldZXPlane()) != 2: # test if inputPolygon is inside the panel
        testResult=False
    else:
        for square in allSquares:
            if rs.PlanarClosedCurveContainment(inputPolygon,square,plane=rs.WorldZXPlane()) != 0 : #test if inputPolygon and square intersect
                testResult=False
                break
            else: #test to make sure there's enough space between squares to be able to construct it
                centerPoint1 = rs.CurveAreaCentroid(inputPolygon)[0] #center of inputPolygon
                distance1 = rs.Distance(rs.PointClosestObject(centerPoint1,inputPolygon)[1],centerPoint1)
                centerPoint2 = rs.CurveAreaCentroid(square)[0] #center of square
                distance2 = rs.Distance(rs.PointClosestObject(centerPoint2,square)[1],centerPoint2)
                if rs.Distance(centerPoint1,centerPoint2) < distance1 + distance2 +minGap:
                    testResult = False
                    break
    return testResult # return either True or False
panelPlane = rs.WorldZXPlane()
panel = rs.AddRectangle(panelPlane,panelHeight,panelWidth)

# Step 3. The Forcing loop
allSquares = [] # list of all squares
for counter in range(iterationNum): # this program will run iterationNum iterations
    sizeSquare = (radiusMax-radiusMin)*counter/iterationNum+radiusMin # gradually change the square size, remap from counter
    newSquare = MakePolygon(sizeSquare) # draw a square permutation
    if TestPolygon(newSquare)==True: # test whether the square permutation is valid or not
        allSquares.append(newSquare)# append the newSquare to the allSquares list if valid
    else: rs.DeleteObject(newSquare)
        # delete the newSquare

# make the surface and extrude
squarePlane = rs.AddPlanarSrf(allSquares+[panel])[0]
line = rs.AddLine((0,0,0),(0,-extrudeHeight,0))
rs.ExtrudeSurface(squarePlane,line)

Hi @marnix.thielman,

I did not look into all the details in your code but it appears like all the squares you are trying to draw get rejected by your TestPolygon function (in the if statement on line 80). I don’t know what this function is supposed to accept or reject, and the code you show above does not run because there is a parameter missing in that function when it is called on line 80, so it’s difficult to provide more advice.

If I bypass that test to force drawing the squares, and add allSquares to the GH output (among others), this is what I see:

Maybe that helps you debug the problem in the TestPolygon function, or the squares you are sending to it?

2 Likes

Hi @pierrec

What the test function did was making sure that the drawn squares would fit inside the panel. And be deleted if they didn’t. I eventually found out what was wrong. I wrongly chose the randomCenter as the point where the primitiveSquare had to rotate around. Which was quite foolish, as i just needed it to rotate it 45 degrees around it’s own center. Which I eventually corrected. So everything is fixed now!

Thanks for your help and interest!
Marnix

PS: I’m very new to Rhino and the Rhinoceros Forums. Is there a way I can mark my question as solved? Or do I just delete it?

Hi -

You should see a checkbox somewhere that you can use to indicate the solution:
image
-wim

Okay I saw this one @wim . It’s just that I found the answer myself and not by a forum reply :slight_smile:

Then you can leave the thread as is, all threads do not need a valid solution. Or post your code fixes and self-accept yourself as the solution :slight_smile: .

1 Like