Rainbow pendulums waves
This model was inspired by Daniel Shiffman's coding Challenge #159:
https://www.youtube.com/watch?v=NBWMtlbbOag
The simulation is pretty close to a real one:
https://www.youtube.com/watch?v=yVkdfJ9PkRQ
I found the equation used to calculate the length of each pendulum here:
https://www.education.com/science-fair/article/pendulum-waves/
Script
L = Slider(1, 15, 0.01, 1, 150, false, true, false, false)
SetValue(L, 15)
#posY = 430
#SetCoords(L, 50, posY)
SetVisibleInView(L, 1, false)
O = (0, 0, 0)
SetVisibleInView(O, 1, false)
speed = 1
t = Slider(0, 1, 0.01, speed, 150, false, true, false, false)
SetVisibleInView(t, 1, false)
g = Slider(0, 15, 0.01, 1, 150, false, true, false, false)
#SetCoords(g, 300, posY)
SetValue(g, 9.81)
SetVisibleInView(g, 1, false)
damping = 0.997
#----------------------------
# Auxiliary names
#----------------------------
Ln = 1...16
Llength = Zip(9.81*(120/(2*pi*(13.44+k+1)))^2, k, Ln)
LnamAng = Zip("angle"+Text(k), k, Ln)
LnamAngV = Zip("angleV"+Text(k), k, Ln)
LnamAngA = Zip("angleA"+Text(k), k, Ln)
SetVisibleInView(LnamAng, 1, false)
SetVisibleInView(LnamAngV, 1, false)
SetVisibleInView(LnamAngA, 1, false)
SetVisibleInView(LnamAng, -1, false)
SetVisibleInView(LnamAngV, -1, false)
SetVisibleInView(LnamAngA, -1, false)
#----------------------------
# Distance between pendulums
#----------------------------
Ldiff = Sequence(k, k, 0, 0.15, 0.01)
size = Length(Ldiff)
#----------------------------
# Lengths of strings
# Define angular velocity
# Define angular acceleration
#----------------------------
Execute(Zip("L"+k+" = "+len+"", k, Ln, len, Llength))
Execute(Zip(name + " = pi * 0.2 + 0.0 * "+k+"", name, LnamAng, k, Ldiff))
Execute(Zip(name + " = 0", name, LnamAngV))
Execute(Zip(name + " = 0", name, LnamAngA))
#----------------------------
# Adjust angle by user
#----------------------------
userAngle = Slider(0, 3.14, 0.01, 1, 150, false, true, false, false)
SetValue(userAngle, pi * 0.5)
SetCaption(userAngle, "θ")
SetLabelMode(userAngle, 9)
#SetCoords(userAngle, 50, posY)
#----------------------------------
# Define the force for each pendulum
#----------------------------------
Execute(Zip("force"+k+" = -g * sin(angle"+k+")", k, Ln))
#----------------------------
# Plot each pendulum in 3D
#----------------------------
Lv = Zip(Vector((0,0,0), (0,k,0)), k, Ln)
TO = Zip(Translate(O, v), v, Lv)
SetVisibleInView(Lv, 1, false)
SetVisibleInView(TO, 1, false)
SetVisibleInView(Lv, -1, false)
SetVisibleInView(TO, -1, false)
Execute(Zip("P"+k+" = Translate( Rotate( ( L"+k+" * sin( angle"+k+" ), -L"+k+" * cos( angle"+k+" ) ) , pi/2 , xAxis), "+v+") ", k, Ln, v, Lv))
Execute(Zip("SetVisibleInView(P"+k+", -1, false)", k, Ln))
#Strings
Execute(Zip("segment"+k+" = Segment("+origin+", P"+k+")", k, Ln, origin, TO))
#Pendulums
Execute(Zip("S"+k+" = Sphere(P"+k+", 0.5)", k, Ln))
Execute(Zip("SetDynamicColor(S"+k+", "+k+"/16, 1, 1, 1)", k, Ln))
#---------------------------------------
# Set value of angle A in
# relation to the length of string
#---------------------------------------
Execute(Zip("SetValue(angleA"+k+", (force"+k+")/"+len+") ", k, Ln, len, Llength))
#----------------------------------------------
# Define two booleans for interaction
#----------------------------------------------
a = false
SetCaption(a, "Play")
SetVisibleInView(a, 1, true)
b = false
SetCaption(b, "Spin")
SetVisibleInView(b, 1, true)
#--------------------------------------
# Frame
# (this can be edited manually)
#--------------------------------------
Q0 = (0,18, 0)
Q0' = (-3, 18, 0)
Q0'' = (3, 18, 0)
Q1 = (0, -1, 0)
Q1' = (-3, -1, 0)
Q1'' = (3, -1, 0)
Q3 = (-7, -1, -17)
Q4 = (7, -1, -17)
Q5 = (-7, 18, -17)
Q6 = (7, 18, -17)
top = Segment( Q0, Q1 )
top' = Segment( Q0', Q0'' )
top'' = Segment( Q1', Q1'' )
leg1 = Segment(Q1', Q3)
leg2 = Segment(Q1'', Q4)
leg3 = Segment(Q0', Q5)
leg4 = Segment(Q0'', Q6)
pl : z = -17.6
SetActiveView(-1)
CenterView( (0, 10, -10) )
ZoomOut(3)
#------------------------------------------------------
# Add these lines to slider 't' on update
#------------------------------------------------------
#Execute(Zip("SetValue(angleA"+k+", (force"+k+")/"+len+") ", k, Ln, len, Llength))
#Execute(Zip("SetValue(angleV"+k+", angleV"+k+" + angleA"+k+"/3)", k, Ln))
#Execute(Zip("SetValue(angleV"+k+", angleV"+k+" * damping)", k, Ln))
#Execute(Zip("SetValue(angle"+k+", angle"+k+" + angleV"+k+"/3)", k, Ln))
#------------------------------------------------------
# Add this line in boolean 'a' on update
#------------------------------------------------------
#StartAnimation(t, true)
#------------------------------------------------------
# Add this line in boolean 'b' on update
#------------------------------------------------------
#If(b==true, SetSpinSpeed(1), SetSpinSpeed(0))