Understanding Functions

hi all,
i am trying to understand how functions and classes work.i have set a small goal to educate myself. so i m trying to do this… dividing circles and adding circles on the points (n) times…
python in general examples are good but since i work with geometry its easy to do such small assignments

my friends on social networks have tried to help me with this with their expertise but i couldnt grasp their complex approaches. i m looking for a simplistic approach possible using function(s).

Edit: I re-wrote the script without recursion, it’s simpler…

This works with a triple nested loop, the outer one that does the concentric rings of circles out to max number of levels, the middle one that divides the level circle into the specified number of segments and the inner loop that divides each segment obtained above into the specified number of sub-segments, then adds the circles. Your pattern above works best with divisions like 4 and 6.

You will see there are a couple of custom functions that are called many times. One divides a circle into equal numbers of points and returns the points, the other divides a line into an equal number of segments and returns the division points. There is also a “wrapper” function for the UI and to launch the main script section.

After having done this, I realize that this is still maybe a too-complex answer to your question… Also, I did not use classes in the example. Sorry… FWIW. --Mitch

"""Script to create rings of concentric overlapping circles
Works best with even numbers of divisions like 4 and 6
Works only in WorldXY plane.  Script by Mitch Heynick 27.05.15"""

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino, math

def DivideCircleExact(origin,rad,n):
    #this function creates "exact" division of points along a circle in XY plane
    div_pts=[]
    inc=2*math.pi/n
    zVec=Rhino.Geometry.Vector3d(0,0,1)
    start_pt=Rhino.Geometry.Point3d(origin.X+rad,origin.Y,0)
    for i in range(n+1):
        xform=Rhino.Geometry.Transform.Rotation(i*inc,zVec,origin)
        div_pts.append(xform*start_pt)
    return div_pts
    
def DivideBetweenPoints(s_pt,e_pt,divs):
    #divides a line between two points into even segments
    #returns (divs+1) division points (including start+end points)
    pts=[]
    vec=e_pt-s_pt
    dist=s_pt.DistanceTo(e_pt)
    vec.Unitize()    
    for i in range(divs):
        pts.append(s_pt+(dist/(divs-1)*i*vec))
    return pts
    
def DivideAddCircles(ctr,rad,divs,max):
    #This is the actual main script, triple nested loop
    
    #add an initial circle to document at the input point
    circ=Rhino.Geometry.Circle(ctr,rad)
    sc.doc.Objects.AddCircle(circ)
    
    #"Outer" loop for getting concentric circles
    for level in range(1,max):
        #get division points along the outer circle
        pl_pts=DivideCircleExact(ctr,level*rad,divs)
        #create polyline from division points
        pl=Rhino.Geometry.Polyline(pl_pts)
        #"explode" polyline into line segments
        segs=pl.GetSegments()
        
        #"Middle" loop through the segments, divide each into level+1 segments
        for seg in segs:
            div_pts=DivideBetweenPoints(seg.From,seg.To,level+1)
            
            #"Inner" loop - add circles at the division points
            #do not add last circle in each segment to avoid dupes
            for j in range(len(div_pts)-1):
                circ=Rhino.Geometry.Circle(div_pts[j],rad)
                sc.doc.Objects.AddCircle(circ)
    
def MultipeOverlapCircles():
    """this "wrapper" function gathers initial parameters from user, 
       then launches the script"""       
    radius=rs.GetReal("Circle radius?",5,minimum=0)
    if not radius: return    
    divs=rs.GetInteger("Number of circle divisions?",6,minimum=2)
    if not divs: return    
    levels=rs.GetInteger("Number of levels?",5,minimum=2,maximum=20)
    if not levels: return    
    orig=rs.GetPoint("Center point for array?")
    if not orig: return
    
    #launch the script
    DivideAddCircles(orig,radius,divs,levels)
    #redraw the screen
    sc.doc.Views.Redraw()
    
MultipeOverlapCircles()
1 Like

Thank u Helvetosaur