Rainbow pendulum 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

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 line 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))