[Edu-sig] thought re graphing calculators ...

kirby urner kirby.urner at gmail.com
Mon Sep 28 23:25:55 CEST 2009

On Mon, Sep 28, 2009 at 12:18 PM, Jeff Rush <jeff at taupro.com> wrote:

<< trim >>

> My hobby in high school was (simple forms of) relativity and orbital
> mechanics due to a strong SF interest, so the first program I ever wrote
> was a time dilation graphing (using punctuation characters) program for
> trips to nearby stars.  I still have it somewhere on teletype paper and
> punch tape.  Along the way I lost interest in physics and found the
> computer far more interesting because it could actually do stuff that
> changed people's lives without a grant and committee approval. :-)
> -Jeff

Speaking of orbital mechanics, this module depending on Visual Python
and Python 2.x (x >= 5) uses various complex number techniques to move
balls in circles, including a moon around a planet.

The sun appears to get bigger and smaller as the default VPython view
strives to adjust the frame automatically, which in this case causes
some auto-zooming.  There's a setting for this, part of the tweakable


Of course this teaches about complex numbers, not about gravity wells
so much.  However, in the animation business, such short cuts are
sometimes acceptable as its the special effect you're after, not
trying to write a simulator or physics engine per se (don't that we
don't have those too in some settings).


By Kirby Urner, 4D Solutions, Portland, Oregon
(copyleft) 2006

Last revised by the original author:  14 Nov 2006 (added Moon class)

Complex numbers provide machinery for rotating in the XY plane,
where the Y axis is "imaginary", the X axis "real".

When two complex numbers multiply, their magnitudes are
multiplied (think of vectors) while their angles get added.
By keeping the magnitudes = 1, we focus on the angles.  A
scale factor applied afterwards can change the radius of
the orbit.

Or we may use the fact that e**(theta*complex(0,1)) takes us
around in a circle.

This 2nd technique shows up in a Planet class, easiest for
having multiple balls, each with its own radius, color, increment,
size of orbit.

Since visual is expecting three floating points (x,y,z) for
position, we use c.real and c.imag to break c into two
floating point numbers for plotting purposes.


import cmath
import math
from visual import *

def orbit1():
    multiply clock hand by a one degree incrementer
    m  = complex(1,0)  # vector pointing to 3 o'clock
    angle = math.radians(1.0)
    # normalized to unit radius (clock diameter = 2)
    onedegree  = complex(cos(angle), sin(angle))
    theball = sphere(pos = (m.real, m.imag), radius = 0.1, color = color.red )
    while True:
        m = m * onedegree  # multiplying causes rotation
        theball.pos = (m.real, m.imag)

def orbit2():
    use e**(theta * i) to get coordinates of rotating ball
    cmath.exp handles a complex number
    onedegree = math.radians(1.0)
    i = complex(0,1)
    angle = 0
    theball = sphere(pos = (1,0,0), radius = 0.1, color = color.green )
    while True:
        angle += onedegree
        coords = cmath.exp(angle * i)
        theball.pos = (coords.real, coords.imag)

class Planet (object):  # subclassing object gives a 'new style' class
    Orbit around (0,0,0) by increment (degrees) per each move invocation
    def __init__(self, distance=1.0, radius=0.1, increment=1, color =
        self.pos = (1.0, 0.0, 0.0)
        self.distance = distance
        self.radius = radius
        self.color = color
        self.theball = sphere(pos = self.pos, radius = self.radius,
color = self.color)
        self.increment = math.radians(increment)
        self.angle = 0

    def move(self):
        self.angle = self.angle + self.increment
        coords = cmath.exp(self.angle * complex(0,1))
        self.coords = (coords.real * self.distance, coords.imag * self.distance)
        self.theball.pos = (self.coords[0], self.coords[1])

class Moon(Planet):
    Orbit around planet (1st argument) by increment (degrees) per each
move invocation
    def __init__(self, planet, distance=1.0, radius=0.1, increment=1,
color = color.red):
        super(Moon,self).__init__(distance, radius, increment, color)
        self.planet = planet

    def move(self):
        self.angle = self.angle + self.increment
        coords = cmath.exp(self.angle * complex(0,1))
        self.coords = (coords.real * self.distance + self.planet.coords[0],
                             coords.imag * self.distance +
        self.theball.pos = (self.coords[0], self.coords[1])

def solarsystem():
    sun = Planet(distance = 0, radius = 0.8, color = color.yellow)
    p1 = Planet(distance=6.0, radius=0.3, increment=0.5, color = color.green)
    p2 = Planet(distance=4.0, radius=0.1, increment=1.0, color = color.red)
    m1 = Moon(p1, distance = 1.0, radius = 0.1, increment = 3.0, color
= color.cyan)

    while True:

> _______________________________________________
> Edu-sig mailing list
> Edu-sig at python.org
> http://mail.python.org/mailman/listinfo/edu-sig

More information about the Edu-sig mailing list