# I can't figure out springs in Python

1. Oct 16, 2011

### Mistborn

For the following Python program, I have to alter the block.Fspring to create realistic spring force, but I can't figure out how to do so. I know the spring force is -k(mag(block.pos - support.pos) - L0), but I don't know how to alter that to apply direction. Please help! I figured I'd use the dot product of that and the parallel unit vector, but it doesn't work...

from visual import *
from visual.graph import * # Loads in graphing module
scene.y = 400 # Moves the visual window down

$# #Constants$#

g = 9.8 #m/s^2
m = 10 #kg Mass of a box
muk = 0.05 # Coefficient of kinetic friction
k = 150 #N/m Spring constant

dt = 0.01 #s Time step
lrate = 500 # Loops per second

zero = vector(0,0,0)

angle = 100
while angle < 0 or angle > 90:
angle = input("Enter the angle of incline in degrees: ")

npar = vector(cos(theta), sin(theta), 0) #unit vector parallel to incline
nperp = vector(-sin(theta), cos(theta), 0) #unit vector perpendicular to incline

blocksize = 0.4 #m size of cubic box
Lincline = 2 #m length of incline
Wincline = 2*blocksize # width of incline
Hincline = 0.1 #m height of incline

#The two lines below calculate the initial position of the block and spring support
blockpos = (Lincline-blocksize)/2*npar + (blocksize+Hincline)/2*nperp
supportpos = -(Lincline-Hincline)/2*npar + (Hincline+blocksize)/2*nperp

print "\nThe block is starting at position ", blockpos, "m."

$# #Objects$#

incline = box(length=Lincline, width=Wincline, height=Hincline,
axis = npar, color=color.blue)

block=box(pos = blockpos, length=blocksize, width=blocksize, height=blocksize,
axis = npar, color=color.green)

support = box(pos=supportpos, length=Hincline, width=Wincline, height=blocksize,
axis = npar, color=color.red)

spring = helix(pos=support.pos, axis = block.pos - support.pos, radius=Hincline,
thickness=Hincline/10, color=color.yellow)

# The lines below set up graphs
graph1 = gdisplay(x=0,y=0,width=400,
xtitle='time (s)',ytitle='x (m)')
graph2 = gdisplay(x=400,y=0,width=400,
xtitle='time (s)',ytitle='y (m)')
graph3 = gdisplay(x=800,y=0,width=400,
xtitle='time (s)',ytitle='v (m/s)')

xgraph=gcurve(gdisplay=graph1,color=color.yellow)
ygraph=gcurve(gdisplay=graph2,color=color.green)

vgraph=gcurve(gdisplay=graph3,color=color.red)

$# #Initial values$#

L0 = mag(block.pos - support.pos) #equilibrium length of spring

block.v = zero #Block is initially at rest

block.Fgrav = vector(0,-g,0)

block.N = - dot(block.Fgrav, nperp)*nperp
block.Fgravpar = dot(block.Fgrav, npar)*npar
#-----------------------------------------------------------------

t = 0

$# #Loop through repetitive calculations$#

# A while loop repeats until the statement becomes false

while t < 10: #Loop for 10 seconds
rate(lrate) #Slows down the animation(smaller lrate, slower animation)

#-----------------------------------------------------------------
# Modify the lines below to the correct expressions.
#-----------------------------------------------------------------
block.Fspring = -k*mag(block.pos - support.pos)*L0
block.Fk = zero
#-----------------------------------------------------------------

block.Fnet = block.Fgrav + block.N + block.Fspring + block.Fk

#-----------------------------------------------------------------
# Modify the lines below to the correct expressions
#-----------------------------------------------------------------
block.a = block.Fnet
block.v = block.v + block.a*dt
block.pos = block.pos + block.v*dt
#-----------------------------------------------------------------

spring.axis = block.pos-support.pos #Updates the spring
t = t + dt #Updates the time

# The lines below graph the following:
# x pos vs time
# y pos vs time
# magnitude of velocity vs time

xgraph.plot(pos=(t, block.pos.x))
ygraph.plot(pos=(t, block.pos.y))
vgraph.plot(pos=(t, mag(block.v)))

$# #Printing results$#

# Unindenting the lines means that the following statements are
# executed AFTER the loop ends

print "The final position is", block.pos, "m."