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 pScale = 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 pdef 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