Tuesday, April 27, 2010

Visual Python

Hi World -
So I finished my Visual Python Project today. Python is a very cool 3-D programming module that John and my class is using to simulate some physics principles.
I created three such projects, "Newton's Cannon," "Ninja," and "Spring SHM."
1. Newton's Cannon
This is a simulation of Newton's classic thought experiment depicting the force of gravity as the key factor in celestial orbits. Using real-world scale objects and a very, very large wooden cannon as a substitute for Newton's proposed space gun atop a mountain, we launch four colorful cannonballs, each with a different initial velocity and trajectory. The program, like Newton's cannon, demonstrates gravity's role as the centripetal force in orbits about a planet and the idea of objects "falling around the earth."

from __future__ import division # The Decimal Rule
from visual import *
from visual.controls import *

# Sunlight
scene.lights = []
distant_light(direction=(10000000,200,1000), color=color.white)

# Dramatis Personae
World = frame()
Earth = sphere(frame=World, pos=(0,0,0), radius=6371000, color=color.white, material=materials.earth)
    # Newton's Super-Advanced/Practically-Magic Cannon
Wheel1 = cylinder(frame=World, pos=(500000,7200000,-1650000), axis=(0,0,1000000), radius=1000000, material=materials.wood)
Wheel2 = cylinder(frame=World, pos=(500000,7200000,650000), axis=(0,0,1000000), radius=1000000, material=materials.wood)
Barrel = cylinder(frame=World, pos=(0,7500000,0), axis=(1500000,1200000,0), radius=960000, material=materials.wood)
BarrelHole = cylinder(frame=World, pos=(0,7500000,0), axis =(1500000,1200000,0),radius= 900000, color=color.black)
World.pos = (0,0,0) # Origin
World.axis = (1,0,0) # Axial Tilt
    # Cannonball 1, A tired soul
Cb1 = sphere(pos=(0.001,7500000,0.001), radius=1000000, color=color.red, material=materials.plastic)
Cb1.velocity = vector(4320,0,36.36)
Cb1.trail = curve (color = Cb1.color)
    # Cannonball 2, "Icarus"
Cb2 = sphere(pos=(0.001,7500000,0.001), radius=1000000, color=color.yellow, material=materials.plastic)
Cb2.velocity = vector(4250, 4000, 36.36)
Cb2.trail = curve (color = Cb2.color)
    # The Little Cannonball that Couldn't
Cb3 = sphere (pos=(0.001, 7500000, 0.001), radius=1000000, color=color.green, material=materials.plastic)
Cb3.velocity = vector(6000, 4000, 36.36)
Cb3.trail = curve (color = Cb3.color)
    # The Champion
CbS = sphere (pos=(0.001, 7500000, 0.001), radius=1000000, color=color.white, material=materials.plastic)
CbS.velocity = vector(7500, 800, 36.36)
CbS.trail = curve (color = CbS.color)

# Constants
G = 6.67e-11                        # Gravitational Constant (m^3*kg^-1*s^-2)
m_ball = 1000000              # mass of cannonballs (kg)
m_earth = 5.9742e24         #  mass of earth (kg)
dt = 0.01                               # Time Step (s)

while True:
    rate(10000)
    World.rotate(angle = pi/43200, axis = (0,1,0), origin = (0,0,0))
    Cb1.trail.append (pos=Cb1.pos)
    Cb2.trail.append (pos = Cb2.pos)
    Cb3.trail.append (pos = Cb3.pos)
    CbS.trail.append (pos = CbS.pos)

# Forces
    # Cannonball 1
    ForceGravityEarthonCb1Mag = G*m_ball*m_earth/pow(Cb1.pos.mag,2)
    ForceGravityEarthonCb1Dir = norm(Earth.pos - Cb1.pos)
    ForceGravityEarthonCb1 = ForceGravityEarthonCb1Mag * ForceGravityEarthonCb1Dir
    # Cannonball 2
    ForceGravityEarthonCb2Mag = G*m_ball*m_earth/pow(Cb2.pos.mag,2)
    ForceGravityEarthonCb2Dir = norm(Earth.pos - Cb2.pos)
    ForceGravityEarthonCb2 = ForceGravityEarthonCb2Mag * ForceGravityEarthonCb2Dir
    # Cannonball 3
    ForceGravityEarthonCb3Mag = G*m_ball*m_earth/pow(Cb3.pos.mag,2)
    ForceGravityEarthonCb3Dir = norm(Earth.pos - Cb3.pos)
    ForceGravityEarthonCb3 = ForceGravityEarthonCb3Mag * ForceGravityEarthonCb3Dir
    # Cannonball S
    ForceGravityEarthonCbSMag = G*m_ball*m_earth/pow(CbS.pos.mag,2)
    ForceGravityEarthonCbSDir = norm(Earth.pos - CbS.pos)
    ForceGravityEarthonCbS = ForceGravityEarthonCbSMag * ForceGravityEarthonCbSDir

# Kinematics
    # Cannonball 1
    Cb1.acceleration = ForceGravityEarthonCb1/m_ball
    Cb1.velocity = Cb1.velocity + Cb1.acceleration*dt
    Cb1.pos = Cb1.pos + Cb1.velocity*dt
    # Cannonball 2
    Cb2.acceleration = ForceGravityEarthonCb2/m_ball
    Cb2.velocity = Cb2.velocity + Cb2.acceleration*dt
    Cb2.pos = Cb2.pos + Cb2.velocity*dt
    # Cannonball 3
    Cb3.acceleration = ForceGravityEarthonCb3/m_ball
    Cb3.velocity = Cb3.velocity + Cb3.acceleration*dt
    Cb3.pos = Cb3.pos + Cb3.velocity*dt   
    # Cannonball S
    CbS.acceleration = ForceGravityEarthonCbS/m_ball
    CbS.velocity = CbS.velocity + CbS.acceleration*dt
    CbS.pos = CbS.pos + CbS.velocity*dt   

# Stop/Land Functions
    if Cb1.pos.mag <= 6371000:
        Cb1.velocity = vector(0,0,0)
        Cb1.rotate(angle = pi/43200, axis = (0,1,0), origin = (0,0,0))
       
    if Cb2.pos.mag <= 6371000:
        Cb2.velocity = vector(0,0,0)
        Cb2.rotate(angle = pi/43200, axis = (0,1,0), origin = (0,0,0))
       
    if Cb3.pos.mag <= 6371000:
        Cb3.velocity = vector(0,0,0)
        Cb3.rotate(angle = pi/43200, axis = (0,1,0), origin = (0,0,0))

    if CbS.pos.mag <= 6371000:
        CbS.velocity = vector(0,0,0)
        CbS.rotate(angle = pi/43200, axis = (0,1,0), origin = (0,0,0))


2. Ninja
This project features a ninja trapped in a dark room. He is scared, tired, hungry, and simply does not want to deal with any more danger. So what does he do? Launch one of his shuriken at the wooden generator level he knows is somewhere along the wall to get the power back on, of course! The ninja sim features projectile motion, use of rotational inertia and the application of conservation of angular momentum in the absence of external torques to help celebrate the ninja's newfound enlightenment and wonderful understanding of physical principles.

from __future__ import division # The Decimal Rule
from visual import *

# Setting
floor = box(length=200, height=0.5, width=40, material=materials.marble)
wall1 = box(pos=(0,10,-20), length=200, height=20, width=0.5, color=color.red, opacity=0.2)
wall2 = box(pos=(0,10,20), length=200, height=20, width=0.5, color=color.red, opacity=0.2)
wall3 = box(pos=(-100,10,0), length=0.5, height=20, width=40, color=color.red, opacity=0.2)
wall4 = box(pos=(100,10,0), length=0.5, height=20, width=40, color=color.red, opacity=0.2)
    # Mood Lighting
lamp = local_light(pos=(40,30,0), color=color.red)
box(pos=lamp.pos, length=2, height=2, width=2, color=color.white, material=materials.emissive)

# Dramatis Persona
 # White Ninja
Ninja = frame()
sphere(frame=Ninja, pos=(1.2,14,0), radius=1.333, color=color.white)
cylinder(frame=Ninja, pos=(0,8,0), axis=(1.2,5,0), radius= 1.667, color=color.white)
ellipsoid(frame=Ninja, pos=(1.2,4,2), axis=(2,1,2.5), length=1, height=10, width=2.8, color=color.white)
ellipsoid(frame=Ninja, pos=(1.2,4,-2), axis=(2,1,-2.5), length=1, height=10, width=2.8, color=color.white)
RArm = ellipsoid(frame=Ninja, pos=(2.9,12,2), length=5, height = 1.8, width=1.8,  color=color.white)
ellipsoid(frame=Ninja, pos=(0.8,12,-3), length=1.8, height = 1.8, width=5, color=color.white)
I_RArm = 125 # Moment of Inertia of Right Arm (kg*m^2)
omega_RArm= -pi/100
Ninja.pos = (0,0.5,0)

# All About Shuriken
shuriken = frame()
shuriken.color = color.black
cylinder(frame=shuriken, pos=(0,0,0), axis=(0,0.25,0), radius=0.5, material=materials.emissive)
box(frame=shuriken, pos=(0.5,0.125,0.25), length=1, width=0.25, height=0.25, material=materials.emissive)
box(frame=shuriken, pos=(-0.5,0.125,-0.25), length=1, width=0.25, height=0.25, material=materials.emissive)
box(frame=shuriken, pos=(-0.25,0.125,0.5), length=0.25, width=1, height=0.25, material=materials.emissive)
box(frame=shuriken, pos=(0.25,0.125,-0.5), length=0.25, width=1, height=0.25, material=materials.emissive)
shuriken.pos = RArm.pos
shuriken.axis = (0,0,1)
shuriken.velocity = vector(80,0,0)
m_shuriken =  0.5  # Mass of Shuriken (kg)
I_shuriken =  0.85413  # Rotational Inertia of Shuriken (kg*m^2)
omega_shuriken = pi/6 # Angular Velocity of Shuriken (rad*s^-1)

target=frame()
target_plank = box(frame=target, length=0.1, width=10, height=20, material=materials.wood)
target.pos=(100,10,0)
m_target = 50 # Mass of Target (kg)
I_target = 500# Rotational Inertia of Shuriken (kg*m^2)
omega_target = 0 # Initial Angular Velocity of Target (rad*s^-1)

# Constants:
t = 0 # Initial Time
g = 9.8 # acceleration due to gravity (m/s/s)
dt = 0.01 # Time Step (s)

# Forces   
while True:
    rate(100)
    t = t + dt

    L_shuriken = (shuriken.pos.z-target.pos.z)*(m_shuriken*shuriken.velocity.x) + I_shuriken*omega_shuriken
    shuriken.rotate(angle=omega_shuriken, axis=(0,1,0), origin=shuriken.pos)
    L_target_1 = (I_target*omega_target + L_shuriken)
   
       
    # Forces
    if shuriken.pos.y <= (floor.pos.y + 0.25):
        Fnorm_shuriken = vector(0, m_shuriken*g, 0)
        omega_shuriken = 0
        shuriken.velocity.y=shuriken.velocity.x=0
    else:
            Fnorm_shuriken = vector(0,0,0)
            Ffriction_shuriken = vector(0,0,0)
        
    Fg_shuriken = vector(0,-m_shuriken*g,0)
    Fnet_shuriken = Fg_shuriken+Fnorm_shuriken
   
    # Kinematics - Shuriken
    shuriken.acceleration = Fnet_shuriken/m_shuriken
    shuriken.velocity = shuriken.velocity + shuriken.acceleration*dt
    shuriken.pos = shuriken.pos + shuriken.velocity*dt

    # Shuriken Stop
    if shuriken.pos.x >= target.pos.x:
        omega_shuriken=0
        Fnorm_shuriken = vector(0,m_shuriken*g,0)
        shuriken.velocity=vector(0,0,0)
        omega_target = L_target_1/I_target

    shuriken.rotate(angle=omega_target, axis=(0,1,0), origin=target.pos)
    target.rotate(angle=omega_target, axis=(0,1,0), origin=target.pos)

    # "The Power's Back On!"
    if omega_target >=0.1:
        wall1.color= wall2.color = wall3.color = wall4.color = lamp.color = color.white

3. Spring SHM
This project is a demonstration of Hooke's Law and how the restoring force of a spring on a mass (wooden block) results in simple harmonic motion. Notable features are the ability to change the block's initial displacement and/or velocity and measure their effects on amplitude. While it isn't as noticeable, the program also shows the role of Newton's second law of motion in defining acceleration's relationship to force.

from visual import *
from visual.controls import * # Activates Control Capacity
from visual.graph import * # Activates Graphing Capacity

# The Simple Harmonic Motion of a Pendulum
    # by Ronald Martin
    # AP Physics - 1st Period, St. Ignatius College Prep.

scene.autoscale = False

# Setting
box(pos=(0,-2.5,0), length=40, height=0.5, width=10, color=color.green) # Floor
Wall = box(pos=(-20.25,-0.25,0), length=0.5, width=10, height=5, color=color.blue)

# Dramatis Personae 1:
x_0 = 0 # block's initial displacement (m)
block = box(pos=(x_0+2.5,0,0), length=5, height=5, width=5, material=materials.wood)
m_block = 10 # Mass of Block (kg)
block.velocity = vector(4,0,0) # Initial Velocity of block (m/s)

Spring = helix(pos=(-20,0,0), radius=2, color=color.yellow)
k = Spring.coils = 20 # Spring Constant (kg/s/s)& Number of Coils

# Constants of Nature
t = 0 # Initial Time (s)
dt = 0.01 # Time Step (s)
g = 9.81 # Acceleration due to gravity (m/s/s)
mu_k = 0.05 # Coefficient of Kinetic Friction

while True:
    rate(100)
    time = t+dt

    # Dramatis Personae (cont'd):
    deltasp =  block.pos-vector(2.5,0,0) # Compression/Stretching of String (m)
    Spring.axis = (block.pos.x-2.5-Wall.pos.x+0.25,0,0) # Spring Cosmetic

    # Forces and Kinematics
    F_g_block = vector(0, -m_block*g, 0)
    F_normal = vector(0, m_block*g, 0)
    F_sp = -k*deltasp
    F_net = F_g_block + F_normal + F_sp

    block.acceleration = F_net/m_block
    block.velocity = block.velocity + block.acceleration*dt
    block.pos = block.pos + block.velocity*dt

If only I could make a video... but alas, CamStudio refuses to work. Maybe later.

Monday, February 22, 2010

THE MOST AWESOME AND AMAZING CIRCUITS LAB EVER!!!!!!!!!!!!!!!!!!!!!!!!

Today, besides working on our Stirling Engine, John and I performed three experiments on current induction using a lemon battery, a solar panel, and a hand-crank generator. We were lucky enough also to have Lucas grace our team with his collaborative presence.

All three systems were capable of generating a flow of electrons, or a current. Why?

· In the lemon battery, we exhibited classic electrochemical principles by introducing a galvanized zinc screw and a copper penny to the fruit’s body. The lemon-battery then acted as a galvanic cell, featuring an oxidation-reduction reaction between the citric acid and each of the zinc and copper metals. In the citric acid electrolyte, the nail served as the anode and the copper as the cathode. Following the net ionic equations below, electrons travelled from the anode through the electrolyte to the cathode.

Anode (oxidation):

· In the solar cell, we exhibited a generated current from the basis of semiconductors involving silicon atoms doped with either gallium or arsenic to create either an n type or p type semiconductor. These semiconductors are linked up to create a type of transistor that when heated allows energy to flow because of the moving electrons that a semiconductor puts out and thus creating a current. This induced current creates an induced voltage that we measure with a voltmeter.

· In the hand crank generator, we used the principle of magnetic inductance to create and induced emf or voltage. By spinning a magnet and thus changing the magnetic field through a loop of wire we change the flux. This flux is related to the induced emf because the magnetic field causes electrons to flow in the wire. This induced current leads to an induced emf and thus voltage or energy can be measured.

Sunday, February 21, 2010

Dreams do come true...

John and I have completed our Stirling Engine, and, even better, we were able to capture it's successful maiden voyage on video!
The fact that it took more than an hour-and-a-half to upload it to YouTube really doesn't bother us because
WE MADE HEAT -> WORK.
Cheers. Pictures to follow.

Monday, February 8, 2010

RTV Smells

Today we completed our pressure vessel top by RTV-ing a flat washer to its top.

We also attached our PCV elbow to our pressure vessel. Ronald came up with the idea of using sandpaper in conjunction with the actual pressure vessel so that the elbow's contour would match perfectly with the can. It was hard work (and seemed to take forever), but it worked! We completed that part of the engine by attaching the (now-curved) elbow to the pressure vessel with RTV. As of this posting, it is now drying:
Next... - WE SEAL AND CLOSE!!

Wednesday, February 3, 2010

PICTURE ONE: RONALD AND JOHN BUILDING THIS THING

Today we are building the first part of the engine the base. We cut using tin snips very carefully. We even had glasses. More will be on the way shortly.

Tuesday, January 19, 2010

Beginning

"Hello World."

Today, John and I begin the scintillating process of reporting our progress on the Stirling Engine Experience. Look forward to some amazing work.

-Ron and John