Pythalon

This weekend I continued my experiments with Python and Avalon.  Before I was hosting Python in an existing app, but now I've started from almost scratch.  I have to clean up the code and wait for the outside world to get new Avalon bits, but I can describe a bit of Pythalon.

Basically it is a Python console below and a Avalon viewing area above.  I injected a variable called RootElement into the Python Processor so I can write little programs against the Avalon OM rooted in RootElement (hence the name).  It turns out to be way fun.  My first example is a little Koch snowflake generator.  I divided the code into two modules:  a platform independent pure math routine, and an Avalon dependent module that creates a Path.  Here's the first section:

from math import *

def vecadd(v1,v2):
return [x+y for x,y in zip(v1,v2)]

def vecsub(v1, v2):
return [x-y for x,y in zip(v1,v2)]

def scalarprod(s, v1):
return [x * s for x in v1]

def dotprod(v1, v2):
t = [x*y for x,y in zip(v1,v2)]
s = 0.0
for x in t:
s += x
return s

def length(vector):
return sqrt(dotprod(vector,vector))

def vector(point1, point2):
return [y - x for x,y in zip(point1, point2)]

def dist(point1, point2):
return length(vector(point1, point2))

def normalize(vector):
l = length(vector)
return scalarprod(1.0/l, vector)

def KochFunc(point1, point2):
if (len(point1) != 2):
return []
v = vector(point1,point2)
n3 = scalarprod(1.0/3.0, v)
c = cos(-pi/3)
s = sin(-pi/3)
n3rotated = [n3[0] * c - n3[1] * s, n3[0]* s + n3[1] * c]
p1 = point1
p2 = vecadd(point1, n3)
p3 = vecadd(p2, n3rotated)
p4 = vecadd(p2,n3)
p5 = point2
return [p1, p2, p3, p4, p5]

def KochFuncOnSequence(s):
retval = []
for i in range(len(s)-1):
retval += KochFunc(s[i], s[i+1])[:4]
retval += KochFunc(s[len(s)-1], s[0])
return retval

and here's the second:

import sys
sys.LoadAssemblyByName("PresentationCore")
sys.LoadAssemblyByName("PresentationFramework")
sys.LoadAssemblyByName("WindowsBase")

from math import *
from System.Windows import *
from System.Windows.Media import *
from System.Windows.Controls import *
from System.Windows.Shapes import *
from Koch import *

def makePoints(sequence):
retval = []
for x in sequence:
retval.append(Point(x[0],x[1]))
return retval

def makeFigure(sequence):
points = makePoints(sequence)
figure = PathFigure()
figure.StartAt(points[0])
for x in points[1:-1]:
figure.LineTo(x)
return figure

def makeGeometry(sequence):
g = PathGeometry()
g.AddFigure(makeFigure(sequence))
return g

def makeSnowFlake(sequence):
g = makeGeometry(sequence)
p = Path()
p.Data = g
return p

Scale = 800.0
StartTriangle = [[0,100], [Scale,100], [Scale/2, Scale*sin(pi/3)+100]]
FirstDegreeFlake = KochFuncOnSequence(StartTriangle)
SecondDegreeFlake = KochFuncOnSequence(FirstDegreeFlake)

def drawFlake(target, degree = 2, brush=Brushes.Cyan):
s = StartTriangle
for i in range(degree):
s = KochFuncOnSequence(s)
p = makeSnowFlake(s)
p.Fill = brush
p.SetValue(Canvas.TopProperty, 50.0)
target.Children.Add(p)
return p

def sampleFlake(target):
stop1 = GradientStop(Colors.Yellow, 0.0)
stop2 = GradientStop(Colors.Orange, 1.0)
stops = GradientStopCollection()
stops.Add(stop1)
stops.Add(stop2)
p = drawFlake(target, 6, LinearGradientBrush(stops))
p.SetValue(Canvas.TopProperty, 120.0)
p.Stroke = Brushes.Violet
return p