Sunteți pe pagina 1din 11

Objective

A tutorial on Cellular Automata and PolyMedia Pixel using Rhino.Python

To develop a cellular automata (Conway's Game of Life) simulation in Rhino.Python.

Pramod Parajuli University of Technology, Sydney 2011


Cellular Automata & PolyMedia Pixel using Rhino.Python Pramod Parajuli, 2011

Agenda ! Algorithm ! Implementation


! ! ! Rhino.Python Cellular Automata Polymedia Pixel

Algorithm
Python, Rhino.Python Cellular Automata Implementation Finalization

! Finalization
! ! Programming style Toolbar creation for UI
Pramod Parajuli, 2011 Cellular Automata & PolyMedia Pixel using Rhino.Python

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata (Conway's Game of Life) In an unlimited universe, there are four(4) basic rules for a cell;
! ! ! ! Any live cell with fewer than two live neighbours dies, as if caused by underpopulation. Any live cell with two or three live neighbours lives on to the next generation. Any live cell with more than three live neighbours dies, as if by overcrowding. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

Cellular Automata (Conway's Game of Life)

In simple terms;
! ! ! ! If already ALIVE and < 2 neighbours, then DIE If already ALIVE and neighbours = 2 or 3, then LIVE If already ALIVE and > 3 neighbours, then DIE If already DEAD and exactly 3 neighbours, then LIVE

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

GoL - practice

Algorithm

Python, Rhino.Python
Cellular Automata Implementation Finalization

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Python quick reference Lists


>>> a = [1, 2, 3] >>> print(a) [1, 2, 3] >>> a[2] = 5 >>> print(a) [1, 2, 5] >>> sum(a) 8
Cellular Automata & PolyMedia Pixel using Rhino.Python

Python quick reference Why lists?


>>> world = [ [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0] ]

>>> b = a >>> a[2] = 10 >>> print(b) ??? >>> b = a[:] >>> a[2] = 30 >>> print(b) ???
Pramod Parajuli, 2011

>>> print(world)
Cellular Automata & PolyMedia Pixel using Rhino.Python Pramod Parajuli, 2011

Python quick reference for loops


>>> for i in world:
print I
[0, 0, 0, 0, 0] [0, 0, 1, 0, 0] [0, 0, 1, 0, 0] [0, 0, 1, 0, 0] [0, 0, 0, 0, 0]

10

Python quick reference Why for loop?


>>> for aRow in world: for aCol in aRow: countNeighbours(aRow, aCol)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 2 0 0 1 1 1 0 1 1 2 1 0 0 0 0 0 0 1 2 3 2 0 0 0 0 0 0 0 0 0 0 0

11

>>> c = [ [1, 2, 3], [4, 5, 6]] >>> len(c) ??? >>> zip(*c) ???

>>> b = [1, 2, 3] >>> sum(b) >>> len(b)


Cellular Automata & PolyMedia Pixel using Rhino.Python

What is countNeighbours ?? We will revisit it later.


Pramod Parajuli, 2011 Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Python quick reference Functions


>>> def add(x, y): return x+y >>> p = 10 >>> q = 5 >>> add(p, q)
15
Cellular Automata & PolyMedia Pixel using Rhino.Python

12

Python quick reference


More on slices
>>> world[1:2]
[[0, 0, 1, 0, 0 ]] >>> z = [1, 2, 3, 4, 5] >>> z[1:4] ??? >>> z[1:4][1] ???
Cellular Automata & PolyMedia Pixel using Rhino.Python

13

>>> p = 10 >>> q = 5 >>> add(p, q) ???

For our world, we need to select only 8 cells around current cell. How to select? We select 3x3 slice and remove the one at the centre. en sum all the 1s in the slice. at will give us the no. of neighbours in the surrounding of a cell.
Pramod Parajuli, 2011

Functions from libraries


>>> import math >>> math.sin(30 * math.pi / 180)
Pramod Parajuli, 2011

Rhino.Python
Some examples First.py
import rhinoscriptsyntax as rs rs.AddPoint([1,2,3]) center = [20, 0, 0] radius = 5 rs.AddSphere(center, radius) " "
Cellular Automata & PolyMedia Pixel using Rhino.Python

14

Rhino.Python drawSine.py
# settin z to a scaled value with intercept z = math.sin(currentRadian) * 70 x = currentAngle y = currentAngle drawEnd = [x, y, z] rs.AddLine(drawStart, drawEnd) drawStart = drawEnd import rhinoscriptsyntax as rs import math def drawSineWave(): print 'Drawing sine wave' sineHeight = rs.GetReal("Please enter height:") x = -30 y = -30 z = math.sin(-30 * math.pi / 180.0) * 70 drawStart = [x, y, z] for currentAngle in range(-90, 90): currentRadian = currentAngle * math.pi / 180.0
Cellular Automata & PolyMedia Pixel using Rhino.Python

15

Second.py
import rhinoscriptsyntax as rs rs.EnableRedraw(False) for i in range(0, 50): if(i%5 == 0): else: rs.AddPoint([i, 0, 0]) rs.AddSphere([i, 0, 0], 0.5)

drawBox.py - demo

rs.EnableRedraw(True)
Pramod Parajuli, 2011

Pramod Parajuli, 2011

Rhino.Python Some bits for Classes and objects


import rhinoscriptsyntax as rs import math # lets create a class Tutorial class Tutorial: def __init__(self, _title, _curveA, _curveB): self.title = _title self.curveA = _curveA self.curveB = _curveB def displayName(self): displayString = 'Title of this object is ' + self.title print(displayString) def drawEdgeSurface(self): surface = rs.AddEdgeSrf([self.curveA, self.curveB]) rs.ObjectColor(surface, [0xff, 0x90, 0xc0])
Cellular Automata & PolyMedia Pixel using Rhino.Python

16
def main(): rstCurve = rs.GetObject("Select rst curve") secondCurve = rs.GetObject("Select second curve") # creating instance of Tutorial newCurve # We will be using this instance holds the data about # curves and also can execute its function on the data. newCurve = Tutorial('Curve drawing tutorial', rstCurve, secondCurve) newCurve.displayName() newCurve.drawEdgeSurface() if( __name__ == '__main__' ): main()
Pramod Parajuli, 2011

Drawing pseudo-surface using lines between curves


Draw 2 curves Divide curves into slices Get the end points of the slices Connect the points with lines

17


Cellular Automata & PolyMedia Pixel using Rhino.Python Pramod Parajuli, 2011

Draw pseudo-surface using lines between curves


import rhinoscriptsyntax as rs class CurveLine: def __init__(self, _strCurveA, _strCurveB, _numSlices): self.strCurveA = _strCurveA self.strCurveB = _strCurveB self._numSlices = _numSlices def drawLines(self): ptsCurveA = rs.DivideCurve(self.strCurveA, self._numSlices, True, True) ptsCurveB = rs.DivideCurve(self.strCurveB, self._numSlices, True, True) counter = 0 for everyPOint in ptsCurveA: rs.AddLine( ptsCurveA[counter], ptsCurveB[counter]) counter += 1 def main(): rstCurve = rs.GetObject("Pick rst curve", 4) secondCurve = rs.GetObject("Pick second curve", 4) newSurface = CurveLine(rstCurve, secondCurve, 100) newSurface.drawLines()
Cellular Automata & PolyMedia Pixel using Rhino.Python

18

Draw pseudo-surface using curves between curves


Draw 3 curves (2 for end edge and 1 for control point Divide all curves into slices Get the endpoints of slices in three di erent lists Form new curves from three points in three lists Use these three points as control points to draw a curve Repeat for all points

19

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Draw pseudo-surface using curves between curves


class CurveSurface: def __init__(self, _strCurveA, _strCurveB, _strCurveC, _numSlices): self.strCurveA = _strCurveA # similarly, create strCurveB, strCurveC self._numSlices = _numSlices def drawCurvesBetween(self): ptsCurveA = rs.DivideCurve(self.strCurveA, self._numSlices, True, True) # similarly, divide strCurveB, strCurveC counter = 0 for everyPOint in ptsCurveA: rs.AddCurve( [ptsCurveA[counter], ptsCurveB[counter], ptsCurveC[counter]]) counter += 1 def main(): rstCurve = rs.GetObject("Pick rst curve", 4) secondCurve = rs.GetObject("Pick second curve", 4) thirdCurve = rs.GetObject("Pick third curve", 4) newSurface = CurveSurface(rstCurve, secondCurve, thirdCurve, 100) newSurface.drawCurvesBetween()
Cellular Automata & PolyMedia Pixel using Rhino.Python

20

Draw surfaces using EdgeSurface between curves


Draw curves between curves as in previous example Draw EdgeSurface in between those curves

21

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Draw surfaces using EdgeSurface between curves


def drawSurfaceBetween(self): ptsCurveA = rs.DivideCurve(self.strCurveA, self.numSlicesL, True, True) ptsCurveB = rs.DivideCurve(self.strCurveB, self.numSlicesL, True, True) ptsCurveC = rs.DivideCurve(self.strCurveC, self.numSlicesL, True, True) counter = 0 previousCurve = rs.AddCurve([ptsCurveA[counter], ptsCurveB[counter], ptsCurveC[counter]]) counter += 1 for everyPOint in ptsCurveA: currentCurve = rs.AddCurve( [ptsCurveA[counter], ptsCurveB[counter], ptsCurveC[counter]]) currentSurface = rs.AddEdgeSrf([previousCurve, currentCurve]) rs.ObjectColor(currentSurface, [counter+70, counter + 150, counter + 200]) previousCurve = currentCurve counter += 1
Cellular Automata & PolyMedia Pixel using Rhino.Python

22

23

Algorithm Python, Rhino.Python

Cellular Automata Implementation


Polymedia Pixel
Finalization

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata (Conway's Game of Life) e algorithm:


! ! ! ! If already ALIVE and < 2 neighbours, then DIE If already ALIVE and neighbours = 2 or 3, then LIVE If already ALIVE and > 3 neighbours, then DIE If already DEAD and exactly 3 neighbours, then LIVE

24

Cellular Automata (Conway's Game of Life) Requirements data structures


! ! ! ! ! List to hold state of life of cells, lets say world[][] List to hold neighbour count of every cell, lets say neighbours[][] List to work for counting and deciding the life state for next stage, lets say buffer[][] Size of the world worldSize Boundary of the world in Rhino3d can be de ned as starting from (worldSize/2) to +(worldSize/2) in XY plane rangeX = worldSize/2 rangeY = worldSize/2

25

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata (Conway's Game of Life) Requirements - functions


! ! ! ! ! A function to create empty list for world, neighbours, and buffer __init__(worldSize) A function to ll initial life states randomly in world - llRandomLives A function to ll initial number of neighbour in neighbours llRandomNeighbours A function to count neighbours given the cell location countNeighbours(row, col) A function to count neighbours of all cells by calling countNeighbours(row, col) iteratively countAllNeighbours

26

Cellular Automata (Conway's Game of Life) Requirements - functions


! A function to decide state of cells for next phase using cellular automata rules and update it in buffer decideLife ! Check state of cell from world ! Check neighbour count from neighbours
! ! Decide next state of the cell Write the state to buffer

27

! !

A function to update graphics on the Rhino3d according to life states in buffer - updateGraphics A function to update world from buffer - updateGraphics
Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Cellular Automata (Conway's Game of Life) Requirements functions


! ! ! ! ! A function to count neighbours given the cell location countNeighbours(row, col) A function to count neighbours of all cells by calling countNeighbours(row, col) iteratively countAllNeighbours

28

29

Algorithm Python, Rhino.Python Cellular Automata Implementation

A function to draw box on the Rhino 3D drawBox(basePoint, length, width, height, objColor) A function to add two lists numerically by elements (used by drawBox) addLists(list1, list2) A main program to de ne thread of control - main
Pramod Parajuli, 2011 Cellular Automata & PolyMedia Pixel using Rhino.Python

Polymedia Pixel
Finalization

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

PolyMedia Pixel Spreading a component object over di erent types of surfaces (polysurface, opensurface) Di erent tasks required to be done to accomplish it
Join and explode surfaces Evaluate surface to retrieve points Explode meshes or mesh objects into sub-meshes Playing with layers Surface normal, and object orientation

30

PolyMedia Pixel Joining surfaces


import rhinoscriptsyntax as rs objs = [] surface1 = rs.GetObject('Select rst surface', rs.lter.surface) surface2 = rs.GetObject('Select second surface', rs.lter.surface) objs.append(surface1) objs.append(surface2) rs.JoinSurfaces(objs, True)
Cellular Automata & PolyMedia Pixel using Rhino.Python

31

Other utility functions such as view and plane for orientation, boundingbox for scaling etc.
Cellular Automata & PolyMedia Pixel using Rhino.Python Pramod Parajuli, 2011

Pramod Parajuli, 2011

PolyMedia Pixel Exploding poly-surface and mesh


import rhinoscriptsyntax as rs newsurface = rs.GetObject("Select a poly-surface object, rs.lter.polysurface) objs = rs.ExplodePolysurfaces(newsurface) rs.MoveObjects(objs, [20, 0, 0]) # similarly, we can explode mesh objects newmesh = rs.GetObject("Select a mesh object", rs.lter.mesh) meshobjs = rs.ExplodeMeshes(newmesh) rs.MoveObjects(meshobjs, [20, 0, 0])

32

PolyMedia Pixel Evaluate surface (Divide surface)


33

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

PolyMedia Pixel Evaluate surface (Divide surface)


def DivideSlab(srf, divisions): domain0 = rs.SurfaceDomain(srf, 0) domain1 = rs.SurfaceDomain(srf, 1) for i in range(divisions+1): u = domain0[0] + (domain0[1]-domain0[0])*i/divisions for j in range(divisions+1): v = domain1[0] + (domain1[1]-domain1[0])*j/divisions point = rs.EvaluateSurface(srf,u,v) drawBox(point, 100, 100, 20, [0x00, 0x90, 0xC0])

34

PolyMedia Pixel Layers


srf = rs.GetObject("Select poly-surface to divide") oldLayer = rs.ObjectLayer(srf) newLayer = rs.AddLayer("dotsLayer") rs.LayerVisible(newLayer, False) rs.EnableRedraw(False) # explode current polysurface into small surfaces rst objSurfaces = rs.ExplodePolysurfaces(srf) rs.CurrentLayer(newLayer) " "
Cellular Automata & PolyMedia Pixel using Rhino.Python

35
for aSurface in objSurfaces: DivideSlab(aSurface, 5, newLayer) rs.LayerVisible(newLayer, True) rs.EnableRedraw(True) rs.LayerVisible(oldLayer, False)

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Pramod Parajuli, 2011

PolyMedia Pixel Surface normal


import rhinoscriptsyntax as rs obj = rs.GetObject("Select a surface", rs.lter.surface) if obj: point = rs.GetPointOnSurface(obj) if point: param = rs.SurfaceClosestPoint(obj, point) normal = rs.SurfaceNormal(obj, param) rs.AddPoints( [point, point + normal] )
Cellular Automata & PolyMedia Pixel using Rhino.Python

36

PolyMedia Pixel Object orientation


import rhinoscriptsyntax as rs obj = rs.GetObject("Select object to orient") if obj: reference = rs.GetPoints(message1="First reference point") if reference and len(reference)>0: target = rs.GetPoints(message1="First target point") if target and len(target)>0: rs.OrientObject( obj, reference, target )

37

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

PolyMedia Pixel Object orientation on surface demo



Cellular Automata & PolyMedia Pixel using Rhino.Python

38

PolyMedia Pixel e algorithm for poly-pixel implementation


Select component object Select surface

39

Check surface type If surface is poly-surface, explode and retain all open surfaces, if not will have only one open surface For all open surface/s, evaluate the surface according to no. of slice user want to do Ask user whether to scale component or not, scale accordingly Make copies of the component object, move them to center of all the evaluated point on the surface, then orient them to surface normal
Pramod Parajuli, 2011 Cellular Automata & PolyMedia Pixel using Rhino.Python Pramod Parajuli, 2011

40

Finalizing
Creating custom toolbar to run script
Edit the icon.

41

Algorithm Python, Rhino.Python Cellular Automata Implementation Polymedia Pixel

Right click on the empty space by the Provide button text and tooltip text. side of existing tabs Click Insert Toolbar In Select Toolbar box, click New Provide name to the toolbar RhinoTutorial Now you can see newly created toolbar.
"

In the macro library, select New Macro In the command box: include followings:
!-_RunPythonScript (" # your python code here )

Finalization

Shift+right click on the icon in the

toolbar.

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Cellular Automata & PolyMedia Pixel using Rhino.Python

Pramod Parajuli, 2011

Finalizing Comments in the source-code


Use # to begin single comments Use to begin and end multiple line comments
---------------------------- Program : <XYZ> Description: <This program is creates > By: <Your name> Date: 31/10/2011 Revision: 1/11/2011 Added new feature 2/11/2011 Optimized function foo etc. ------------ import rhinoscriptsyntax as rs # YOUR CODE STARTS HERE # For Classes, Functions, Special data structures also, write their name, description, return values etc.
Cellular Automata & PolyMedia Pixel using Rhino.Python

42

Pramod Parajuli, 2011

S-ar putea să vă placă și