Gravity Sim CODE ( Netlogo environment )
; GravitySim 1.5 (and NetLogo 5.0.4)
; Original version 1.0 release date: 20 November 2012.
; v 1.1 -- 01 December 2012 { Fixed typographical errors in dialog boxes. }
; v 1.2 -- 27 January 2013 { Added "Software test" simulation; fixed reference frame synchronous rotation animation in sims; updated some text. }
; v 1.3 -- 27 March 2013 { Added BIG switch (increases size of trace dots by 1 pixel). }
; v 1.4 -- 15 May 2013 { Improved presentation of text in the general message box. }
; v 1.5 -- 24 August 2013 { Improved the communication in some text messages. Slight improvements to initial demonstration ([← Show Me] button) interface and 'Empty space' simulation interface. }
; NOTE: btnShowMe routine is NOT tick-based; Netlogo "view updates" mode must be set to "continuous".
extensions [sound] ; only 2 sounds exist (startup sound: ./GSrsc/astronaut40s.au, LRO/Apollo sound: ./GSrsc/OneSmallStep8s.au)
;=========================================================================================================================================================================================
; variable definitions
;=========================================================================================================================================================================================
turtles-own
[ My-ax ; acceleration x-component
My-ay ; acceleration y-component
My-vx ; velocity x-component
My-vy ; velocity y-component
My-px ; position x-component
My-py ; position y-component
My-fx ; frame x-coordinate (plotted)
My-fy ; frame y-coordinate (plotted)
MyRadius ; distance from origin (GM)
MyRelDistance ; distance from the centroid (i.e., orange ball)
MyRelVelocity ; velocity relative to the centroid
EnergyStart ; kinetic energy + gravitational potential energy *relative to the centroid (i.e., the orange ball)*
EnergyNow ; ideally, should be identical to EnergyStart when operating in empty space, but not so when the orange ball orbits a source mass
MyPhaseInit ; initial phase angle in orbit in degrees
MyOmega ; angular velocity applicable iif the ball has a known circular orbit
MyPhaseDeg ; phase angle in orbit in degrees (iif the ball has a known circular orbit)
]
globals
[
; stored values of the orange reference ball
OrangeMy-px
OrangeMy-py
OrangeMy-vx
OrangeMy-vy
OrangeMyRadius
OrangeMyPhaseDeg
; interface reporters (brown boxes)
; inside left frame
OrbitalPeriodShow
OrbitalSpeedShow
OrbitalRadiusShow
cShowGM
; main controls
Orange_Ball_MassShow
Simulation_IntervalShow
Time_IntervalMultiplier ; not shown, but related to Simulation_IntervalShow (time interval in seconds = Simulation_Interval: * Time_IntervalMultiplier)
Test_Mass_Separation*:_Units
; top right
FrameDimensionsShow
GridSquareDimensionsShow
Trace_IntervalShow
Trace_IntervalMultShow ; what the slider units are being multiplied by
TraceSecondsMultiplier ; not shown, but related to units: if minutes (60), if hours (3600), if years (3.15569E7)
; Dashboard
Real-timeShow
Run-timeShow
SimulationSpeed
DistanceChange
Arcseconds
fre ; fractional range error
avg-fre
sum-fre ; not reported, used to calculate avg-fre = (sum-fre / ticks)
MaxRangeShow
MaxVelocityShow
; values for shown values, above
MaxRange ; maximum distance of a ball relative to the orange ball
MaxRangeColor ; color of the ball
MaxVelocity ; maximum velocity of a ball relative to the orange ball
MaxVelocityColor ; color of the ball
; lock control values at start of simulation
LockSynchronous_Rotation
LockR
LockChoose_Simulation:
LockOrange_Ball_Mass:
LockTest_Mass_Separation*:
LockSimulation_Interval:
LockOrbit_Stops_At:
LockFrame_Dimension:
Lockx1
LockTrace_Interval:
LockTimePerTick ; = LockSimulation_Interval: * Time_IntervalMultiplier
; switches
bShowMe ; tells setup-2-Graphics that it was called by btnShowMe, not by startup or btnReset
bNoSplash ; tells setup-2-Graphics not to use splash screens — we about to run a simulation
bSetUpButtonLocked ; when running (= true), user cannot click the setup button before a reset
bShowOrbitClicked ; stops the current simulation (but user should toggle [Run Simulation] instead)
bSetUpButtonClicked ; btnShowMe should not work afterwards
bFreeFall ; user chose "Radial free fall" simulation
bEarthExists ; user chose "Empty space (no Earth)" simulation
bEndOfSimuation ; Orbit_Stops_At: was reached
bResetTimer ; used in btnRun to start the Run-time timer
bPreciseColors ; if false (default) "lime" is reported as "green"; "sky" is reported as "blue"
; screen size management
bNotHD ; true if this is not the HD version; set in setup-0-Clear&Reset
ScreenScale
Screen_dx
Screen_dy
OrbitRadius
CenterX
GyroOffset
; check values for max values
CheckMaxRange ; checking maximum distance
CheckMaxRangeColor ; color of the ball
CheckMaxVelocity ; checking max velocity
CheckMaxVelocityColor ; maximum velocity of a ball relative to the orange ball
; set constants
cSourceBodyGM ; set to the JPL HORIZONS value for the Earth (or the Moon)
OrbitalPeriod ; depends on orbit selected; set in setup-2-Graphics
cOrbitalSpeed ; depends on orbit selected; set in setup-2-Graphics
; calculated constants
OrbitalRadius ; calculated per orbital mechanics assuming an idealized zero eccentricity
CentroidGM ; = G * LockOrange_Ball_Mass:
cPixelsPerMeter ; = 400 / LockFrame_Dimension:
; calculated simulation variables (physics)
Real-time ; LockTime_Interval * ticks
FrameIdealTheta ; = Real-time / OrbitalPeriod * 360 (i.e., if Real-time = OrbitalPeriod, then FrameIdealTheta = 360)
dx-correction ; the x position correction of the orange ball to be applied to all other balls
dy-correction ; the y position correction of the orange ball to be applied to all other balls
ffv-correction ; free fall velocity correction
; miscellaneous
LastOutput ; what was last typed to output
LastAlert ; what was last temporarily displayed in output
LastReport ; time in seconds that the last report was written to output
OutputHeader ; text description of simulation to run
PadLeftSpaces ; used by repNumber, which pads PadLeftSpaces to the left of numbers
SimSettings ; Text of the settinf for output
AutoStopAngle ; the angle correlated to Orbit_Stops_At: value
Run-Time ; used to calculate Run-timeShow
LastRun-time ; used to calculate SimulationSpeed
ShowM51 ; compare simulation to M51
; names of display turtles for easy reference
tOrbitalSpeedCalc ; used to display data via its label
tOrbitalSpeedSim ; used to display data via its label
tOrbitalRadius ; used to display data via its label
tOrbitalPeriod ; used to display data via its label
tPartOfT ; used to display (PhaseAngle / 360)
tGM ; used to display data via its label
tOrangeMass ; used to display data via its label
tTraceInterval ; used to display data via its label
; names of other turtles for easy reference
tMarker ; used for drawing stuff and copyright notice on exported view
tMessage ; used to display a message via its label.
tMessage2 ; used to display a message via its label (second line).
tReferenceFrame ; the little reference frame that moves
tGyroOrange ; magnified orange ball for [← Show Me] button
tGyroRed ; the red ball for [← Show Me] button
tGyroGreen ; the green ball for [← Show Me] button
tLittleGyroRed ; the red ball inside the orbiting frame for [← Show Me] button
tLittleGyroGreen ; the green ball inside the orbiting frame for [← Show Me] button
tOrangeBall ; center test mass
; corner test masses
tRedBall_TL
tGreenBall_TR
tMagentaBall_BL
tYellowBall_BR
; radial test masses (top/bottom center)
tBlueBall_TC
tVioletBall_BC
; lateral test masses (middle left/right)
tPinkBall_ML
tWhiteBall_MR
]
breed [ OrbitData OrbitDatum ] ; the display turtles in the left pane
breed [ radials radial ] ; the two radial balls (blue / violet)
breed [ laterals lateral ] ; the two lateral balls (pink / white)
breed [ corners corner ] ; the four corner balls
to testme ; place to test message output
; let MsgPhrase ""
; let OutputPhrase ""
clear-output
end
;=========================================================================================================================================================================================
; physics
;=========================================================================================================================================================================================
; *** START OF ALL THE PHYSICS *** *** START OF ALL THE PHYSICS *** *** START OF ALL THE PHYSICS *** *** START OF ALL THE PHYSICS *** *** START OF ALL THE PHYSICS ***
; This section has been put at the top to make technical code review easy.
; Everthing seen in the simulations is controlled exclusively by this code.
; This is the only calling application for the physics routines, below.
; It is called exclusively by the <btnRun> routine, PART 4: Simulation.
to physics-0-sequence
physics-1-position ; new position = old position + (old velocity * Δt)
physics-2-position-fix ; Correct position of frame based on perfect knowledge of orange ball dynamics (given a circular orbit at fixed angular velocity).
physics-3-velocity ; new velocity = old velocity + (old acceleration * Δt)
physics-4-velocity-fix ; *Only if free falling*, correct the velocity of the frame based on energy conservation calculated from total Δr from original starting position.
physics-5-properties ; Update the properties of the test masses (but not the orange ball) here.
physics-6-accel ; new acceleration = acceleration of Earth on orange ball at new position {MyRadius} (set in physics-5-properties)
end ; + any acceleration of orange ball on test masses at there new positions in the frame
to physics-1-position
; new position = old position + (old velocity * Δt)
set My-px (My-px + (My-vx * LockTimePerTick))
set My-py (My-py + (My-vy * LockTimePerTick))
end
; After each tick, we know exactly where the orange ball (i.e., the reference frame centroid) should be.
; This routine shifts the entire frame (and the relative locations of all test masses) to the correct location.
; By doing this, the very small error incurred over each tick does not add up over the simulation.
to physics-2-position-fix
if not bFreeFall and bEarthExists
[ if self = turtle tOrangeBall ; always gets set first in btnRun
[ let RoughRadius (sqrt(My-px ^ 2 + My-py ^ 2))
set fre ((RoughRadius - OrbitalRadius) / OrbitalRadius)
set sum-fre sum-fre + fre
set avg-fre (sum-fre / (ticks + 1))
let idealX OrbitalRadius * cos repMathAngle FrameIdealTheta
let idealY OrbitalRadius * sin repMathAngle FrameIdealTheta
set dx-correction idealX - My-px
set dy-correction idealY - My-py
set MyPhaseDeg FrameIdealTheta ; the orange ball is always corrected to the ideal phase angle
]
set My-px My-px + dx-correction
set My-py My-py + dy-correction
]
end
to physics-3-velocity
ifelse self != turtle tOrangeBall and MyRelDistance = 0
[ ; This test mass has been absorbed by the orange ball and is hidden.
set My-vx OrangeMy-vx
set My-vy OrangeMy-vy
]
[
; new velocity = old velocity + (old acceleration * Δt)
set My-vx (My-vx + (My-ax * LockTimePerTick))
set My-vy (My-vy + (My-ay * LockTimePerTick))
]
end
; In the case of radial free fall, we know exactly how fast the orange ball should be moving for its range based on energy conservation.
; This routine calculates the difference between the simulated velocity and the known actual value and corrects the velocitues of all the balls accordingly.
; By doing this, the small error incurred over each tick does not add up over the simulation.
to physics-4-velocity-fix
if bFreeFall ; Energy conservation in free fall allows for this correction.
[ if ( (int(Real-time) != LastReport) and (remainder int(Real-time) (LockTrace_Interval: * TraceSecondsMultiplier) = 0) ) or ( MyRadius < (6371 * 2 * 1000) ) ; trace intervals and within 2 Earth radii
[ if self = turtle tOrangeBall ; always gets set first in btnRun
[ let ffEnergyCalcV 0 - sqrt( 2 * cSourceBodyGM * ( 1 / My-py - 1 / OrbitalRadius) ) ; This is the known velocity at this range from energy considerations; 0 for tick 0.
set ffv-correction ffEnergyCalcV - My-vy
]
set My-vy My-vy + ffv-correction
if bFreeFall and ( self = turtle tOrangeBall or self = turtle tBlueBall_TC or self = turtle tVioletBall_BC)
[ set My-vx 0 ] ; Free-falling *radial* balls never have any x-velocity, so don't introduce any tiny errors induced by the "atan" function.
]
]
if not bEarthExists and self != turtle tOrangeBall
[ ; At periapsis, the body tends to swing out too wide, so we bring it in to the correct radius based on constant energy.
; We need to pre-update these three values, but not the energy.
set MyRadius sqrt(My-px ^ 2 + My-py ^ 2)
if MyRadius < 10
[ set MyRelDistance MyRadius
set MyRelVelocity sqrt( My-vx ^ 2 + My-vy ^ 2)
let MyKineticEnergy ( 0.0005 * MyRelVelocity ^ 2) ; = (0.5 * m * v^2) in joules *relative to the orange ball*
let MyPotentialEnergy (0 - ( CentroidGM * 0.001 / MyRelDistance )) ; - (GMm / r) in joules *relative to the orange ball*
let RoughEnergyNow MyKineticEnergy + MyPotentialEnergy ; This should = EnergyStart.
let EnergyError RoughEnergyNow - EnergyStart
if EnergyError != 0
[ let CorrectPotentialEnergy MyPotentialEnergy - EnergyError
let CorrectRadius abs (CentroidGM * 0.001 / CorrectPotentialEnergy)
let CorrectionFactor CorrectRadius / MyRadius
set My-px My-px * CorrectionFactor
set My-py My-py * CorrectionFactor
]
]
]
end
to physics-5-properties
ifelse self = turtle tOrangeBall
[ ; orange ball only:
; First, get the changes, based on the old values.; how far did it move from last position?
if ticks > 0 ; We can't calculate this on the 0th tick.
[ set DistanceChange uCenterText22 (repNumber (sqrt((My-px - OrangeMy-px) ^ 2 + (My-py - OrangeMy-py) ^ 2) / 1000) 6)
ifelse bFreeFall [ set Arcseconds uCenterText22 "N/A" ][ set Arcseconds uCenterText22 (repNumber ((MyPhaseDeg - OrangeMyPhaseDeg) * 3600) 6) ]
]
; Now that we have the changes, above, update the orange ball values for reference by the other balls.
set OrangeMy-px My-px
set OrangeMy-py My-py
set OrangeMy-vx My-vx
set OrangeMy-vy My-vy
set OrangeMyRadius MyRadius
set OrangeMyPhaseDeg MyPhaseDeg
if bFreeFall [ set MyRadius sqrt(My-px ^ 2 + My-py ^ 2) ] ; otherwise, it is a constant
]
[ ; test masses only:
set MyRadius sqrt(My-px ^ 2 + My-py ^ 2)
set MyRelDistance sqrt( (My-px - OrangeMy-px) ^ 2 + (My-py - OrangeMy-py) ^ 2)
set MyRelVelocity sqrt( (My-vx - OrangeMy-vx) ^ 2 + (My-vy - OrangeMy-vy) ^ 2)
set EnergyNow (( 0.0005 * MyRelVelocity ^ 2) - ( CentroidGM * 0.001 / MyRelDistance )) ; = (0.5 * m * v^2) - (GMm / r) in joules *relative to the orange ball*
]
end
; Determine acceleration vectors using inverse square law *based on MyRadius* .
to physics-6-accel
let angle 0
let EarthAccelerationX 0
let EarthAccelerationY 0
if bEarthExists
[ set angle repMathAngle atan My-px My-py
; new acceleration is calculated from new radius relative to Earth
set EarthAccelerationX 0 - (cos angle * (cSourceBodyGM / MyRadius ^ 2))
set EarthAccelerationY 0 - (sin angle * (cSourceBodyGM / MyRadius ^ 2))
]
; If it has mass, what is the gravitational acceleration of the orange ball on a local test mass?
let CentroidAccelerationX 0
let CentroidAccelerationY 0
if self != turtle tOrangeBall
[ ; What is the position of the test mass in the frame relative to the orange ball?
let RelativeX My-px - OrangeMy-px
let RelativeY My-py - OrangeMy-py
let RadiusToCentroid sqrt(RelativeX ^ 2 + RelativeY ^ 2)
ifelse RadiusToCentroid <= 1
[ ; Test mass has crashed into the orange ball and is absorbed.
set MyRelDistance 0 ; The ball hit the orange centroid ball and is absorbed by it; it dies.
set My-px OrangeMy-px
set My-py OrangeMy-py
die
]
[
; Based on its relative position, this is the acceleration of the orange ball on the test mass.
set angle repMathAngle atan RelativeX RelativeY
set CentroidAccelerationX 0 - cos angle * (CentroidGM / RadiusToCentroid ^ 2) ; the "toy model" acceleration of the orange ball
set CentroidAccelerationY 0 - sin angle * (CentroidGM / RadiusToCentroid ^ 2) ; the "toy model" acceleration of the orange ball
]
]
; new acceleration = linear combination of Earth acceleration and orange ball acceleration
set My-ax EarthAccelerationX + CentroidAccelerationX
set My-ay EarthAccelerationY + CentroidAccelerationY
end ; physics-6-accel
; *** END OF ALL THE PHYSICS *** *** END OF ALL THE PHYSICS *** *** END OF ALL THE PHYSICS *** *** END OF ALL THE PHYSICS *** *** END OF ALL THE PHYSICS ***
;=========================================================================================================================================================================================
; BUTTONS
;=========================================================================================================================================================================================
to btnShowMe ; This routine is NOT tick-based; Netlogo "view updates" mode must be set to "continuous".
if hStartupHalt [ user-message "[ Halt ] clicked during startup; restart required.\n\n" stop ]
if bEndOfSimuation
[ let MsgPhrase "This button can be only used after\n"
set MsgPhrase word MsgPhrase "clicking [ Show This Orbit ].\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
stop
]
if bSetUpButtonClicked
[ let MsgPhrase "Click [ Run Simulation ] instead.\n\n"
set MsgPhrase word MsgPhrase "This button can be only used after\n"
set MsgPhrase word MsgPhrase "clicking [ Show This Orbit ].\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
stop
]
if bEarthExists and R != LockR
[ let MsgPhrase "The orbit setting (R) is different from the displayed orbit.\n"
set MsgPhrase word MsgPhrase "To change orbits, first click [ Show This Orbit ].\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set bNoSplash false
stop
]
if R = 1 or R = 10
[ let MsgPhrase "This button does not function for the ISS or LRO orbits;\n"
set MsgPhrase word MsgPhrase "the reference frame icon is too small.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
stop
]
set bShowMe true
uPark-tMessage ; just in case this is right after a sim
ask turtle tOrangeBall [ hide-turtle ]
ask turtle tGyroOrange [ show-turtle ]
import-drawing "./GSrsc/spacecraft.png"
ask turtle tReferenceFrame [ set shape "spacecraft" ]
set FrameDimensionsShow uCenterText22 "~ 3 m × 3 m"
set GridSquareDimensionsShow uCenterText22 "N/A"
let OutputPhrase "*** A gyroscope suspended in space maintains its orientation relative to the ‘fixed quasars.’ ***\n\n"
set OutputPhrase word OutputPhrase "Note that the spacecraft is represented in miniature at the 12 o'clock position in the left frame.\n"
set OutputPhrase word OutputPhrase "Thus, this gyroscope (orange ball) always points in the general direction of the North Star (Polaris).\n\n"
set OutputPhrase word OutputPhrase "The ‘spacecraft’ is idealized in that it exerts no forces whatsoever on the gyroscope and the gyro is ideally\n"
set OutputPhrase word OutputPhrase "located at the spacecraft’s center of mass; thus, this gyro never translates in x, y, or z from the origin.\n"
clear-output
beep
output-type OutputPhrase
let MsgPhrase "* This will be a demonstration, not a simulation. *\n\n"
set MsgPhrase word MsgPhrase "EXPERTS:\n"
set MsgPhrase word MsgPhrase "Be patient; Part IV communicates the key concept.\n"
set MsgPhrase word MsgPhrase "*** It demonstrates behavior that is not intuitive. ***\n\n"
set MsgPhrase word MsgPhrase "Please read the important information newly posted\n"
set MsgPhrase word MsgPhrase "to the general message box. If it is partially obscured,\n"
set MsgPhrase word MsgPhrase "you may drag this dialog box out of the way.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set Synchronous_Rotation true
set MsgPhrase "I. Center-of-mass gyro : ↕Synchronous_Rotation -On-\n\n"
set MsgPhrase word MsgPhrase "In this case, the reference frame keeps the same ‘face’\n"
set MsgPhrase word MsgPhrase "pointing Earthward like a typical satellite. This implies\n"
set MsgPhrase word MsgPhrase "that a free-floating gyroscope will rotate in the frame.\n"
set MsgPhrase word MsgPhrase "Thus, this is *not* an inertial reference frame because\n"
set MsgPhrase word MsgPhrase "internal objects are subject to centripetal acceleration.\n\n"
set MsgPhrase word MsgPhrase "DEFINITION:\nThe “inertial reference frame” of an object is an idealized\n"
set MsgPhrase word MsgPhrase "reference frame in which the object experiences no forces.\n\n"
set MsgPhrase word MsgPhrase "NOTE:\nHold mouse-down inside the frame to stop action;\n"
set MsgPhrase word MsgPhrase "3, 6, and 9 o'clock positions are most helpful.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
let DoNext false
while [ not DoNext ]
[ drawOrbit
set DoNext user-yes-or-no? "Continue with the next part?\n(Click 'No' to repeat the last demo.)\n\n"
]
wait 0.5
set Synchronous_Rotation false
set OutputPhrase word OutputPhrase "\n"
set OutputPhrase word OutputPhrase "=============================================================================================================\n"
set OutputPhrase word OutputPhrase "If the gyroscope does not rotate, an internal observer without a window does not know that the spacecraft\n"
set OutputPhrase word OutputPhrase "is in orbital motion, at least not by consulting the orientation of a gyroscope.\n\n"
beep
output-type OutputPhrase
set MsgPhrase "II. Center-of-mass gyro : ↕Synchronous_Rotation -Off-\n\n"
set MsgPhrase word MsgPhrase "The spacecraft will now behave naturally; similar to the\n"
set MsgPhrase word MsgPhrase "gyroscope, it will keep the same orientation relative to\n"
set MsgPhrase word MsgPhrase "the ‘fixed quasars’ over its orbit.\n\n"
set MsgPhrase word MsgPhrase "The free-floating gyroscope does not transate or rotate;\n"
set MsgPhrase word MsgPhrase "this is then the gyroscope’s *inertial reference frame* .\n"
set MsgPhrase word MsgPhrase "See additional detail in the general message box.\n\n"
set MsgPhrase word MsgPhrase "NOTE:\n"
set MsgPhrase word MsgPhrase "The fact that the same side of the Moon always faces the\n"
set MsgPhrase word MsgPhrase "Earth is due to “gravitational tidal locking” caused by a\n"
set MsgPhrase word MsgPhrase "mass asymmetry; if one side of the Moon were not more\n"
set MsgPhrase word MsgPhrase "massive than the other, this would not occur.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set DoNext false
while [ not DoNext ]
[ drawOrbit
set DoNext user-yes-or-no? "Continue with the next part?\n(Click 'No' to repeat the last demo.)\n\n"
]
wait 0.5
ask turtle tLittleGyroRed [ show-turtle ]
ask turtle tLittleGyroGreen [ show-turtle ]
display ; always call display before a dialog box
let YNphrase "Two gyroscopes (small red and green circles) have been\n"
set YNphrase word YNphrase " added to the miniature orbiting spacecraft on the left.\n\n"
set YNphrase word YNphrase "Are both of them adequately visible?\n\n"
ifelse not user-yes-or-no? YNphrase
[ ask turtle tLittleGyroRed [ set size 4 ]
ask turtle tLittleGyroGreen [ set size 4 ]
ask turtle tReferenceFrame [ set shape "spacecraft2" ]
; In this case, they appear the same size (40), not a little larger (43).
ask turtle tGyroRed [ set size 40 * ScreenScale ]
ask turtle tGyroGreen [ set size 40 * ScreenScale ]
set MsgPhrase "They are now bigger; you should see them clearly.\n\n"
set MsgPhrase word MsgPhrase "Click [ OK ]; the same gyroscopes will appear on the right…\n\n"
user-message MsgPhrase
]
[
user-message "Click [ OK ]; the same gyroscopes will appear on the right…\n\n"
]
ask turtle tGyroRed [ show-turtle ]
ask turtle tGyroGreen [ show-turtle ]
set Synchronous_Rotation true
set OutputPhrase word OutputPhrase "=============================================================================================================\n"
set OutputPhrase word OutputPhrase "The red and green gyros are on the same ideal circular orbit as the orange gyro and slightly out of phase.\n"
set OutputPhrase word OutputPhrase "This ‘experiment’ assumes the idealization that the spacecraft environment has no effect on the behavior\n"
set OutputPhrase word OutputPhrase "of any gyroscope; it simply functions as a convenient visual reference frame in which to observe them.\n"
set OutputPhrase word OutputPhrase "Therefore, the only modeled force acting on the three gyroscopes is the inverse-square gravitational force\n"
set OutputPhrase word OutputPhrase "of an idealized ‘point-mass’ Earth.\n\n\n"
beep
output-type OutputPhrase
set MsgPhrase "III. Multiple gyros : ↕Synchronous_Rotation -On-\n\n"
set MsgPhrase word MsgPhrase "Please read the important information newly posted\n"
set MsgPhrase word MsgPhrase "to the general message box.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set DoNext false
while [ not DoNext ]
[ drawOrbit ; calls display
set DoNext user-yes-or-no? "Continue with the next part?\n(Click 'No' to repeat the last demo.)\n\n"
]
wait 0.5
set Synchronous_Rotation false
set MsgPhrase "IV. Multiple gyros : ↕Synchronous_Rotation -Off-\n\n"
set MsgPhrase word MsgPhrase "The conditions are identical to those in Part II, in which\n"
set MsgPhrase word MsgPhrase "the orange gyroscope at the center of mass is immobile;\n"
set MsgPhrase word MsgPhrase "this is the orange gyro’s *inertial reference frame* .\n\n"
set MsgPhrase word MsgPhrase "The other two gyroscopes are on the identical orbit;\n"
set MsgPhrase word MsgPhrase "how do you expect them to behave over the orbit\n"
set MsgPhrase word MsgPhrase "from the perspective of this frame of reference, in\n"
set MsgPhrase word MsgPhrase "which the orange gyro experiences zero net force?\n\n"
set MsgPhrase word MsgPhrase "This demonstration will make it obvious. Be sure \n"
set MsgPhrase word MsgPhrase "to closely observe the gyros shown on the left —\n"
set MsgPhrase word MsgPhrase "hold mouse-down inside the frame to stop action.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set DoNext false
while [ not DoNext ]
[ drawOrbit ; calls display
set DoNext user-yes-or-no? "Continue? (Click 'No' to repeat the last demo.)\n\n"
]
wait 0.5
set MsgPhrase "KEY CONCEPT:\n"
set MsgPhrase word MsgPhrase "It is a general principle of nature that a collection of\n"
set MsgPhrase word MsgPhrase "objects, which orbits *another object*, will ‘wind up.’\n\n"
set MsgPhrase word MsgPhrase "----------------------------------------------\n\n"
set MsgPhrase word MsgPhrase "This principle is independent of scale; it is just as true\n"
set MsgPhrase word MsgPhrase "for a “toy model” consisting of a few marbles orbiting\n"
set MsgPhrase word MsgPhrase "the Earth as for a collection of billions of stars in a\n"
set MsgPhrase word MsgPhrase "spiral galaxy disk, which, as a collective unit, orbits\n"
set MsgPhrase word MsgPhrase "some distant barycenter within the host cluster.\n\n"
set MsgPhrase word MsgPhrase "This proves to be relevant to the “dark matter problem”\n"
set MsgPhrase word MsgPhrase "as concerns interpreting spiral galaxy rotation curves.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
if R = 3 ; default startup orbit
[ set MsgPhrase "It may be instructive to switch to a different orbit\n"
set MsgPhrase word MsgPhrase "(e.g., “Moon”) and run this demonstration again.\n"
set MsgPhrase word MsgPhrase "Any illusion that the proximity of the Earth is\n"
set MsgPhrase word MsgPhrase "somehow related to the observed phenomena\n"
set MsgPhrase word MsgPhrase "will be dispelled.\n\n"
set MsgPhrase word MsgPhrase "AFTER you click [ OK ] in the *following* dialog box:\n"
set MsgPhrase word MsgPhrase "1. Move the small red tab on the vertical green slider\n"
set MsgPhrase word MsgPhrase " (R, far left) to “Moon” (the next-to-highest position).\n"
set MsgPhrase word MsgPhrase "2. Click [ Show This Orbit ] to change orbits.\n"
set MsgPhrase word MsgPhrase "3. Click [ ← Show Me ] to run this demo again.\n\n"
user-message MsgPhrase
]
set MsgPhrase "This brief demonstration is now concluded.\n\n"
set MsgPhrase word MsgPhrase "After running this demo any number of times you wish,\n"
set MsgPhrase word MsgPhrase "read “WHAT NEXT?” under the | Info | link (top of screen).\n\n"
user-message MsgPhrase
uPark-tMessage
; Return all turtles to their original size.
ask turtle tLittleGyroRed [ set size 3 hide-turtle ]
ask turtle tLittleGyroGreen [ set size 3 hide-turtle ]
ask turtle tGyroRed [ set size 43 * ScreenScale hide-turtle ]
ask turtle tGyroGreen [ set size 43 * ScreenScale hide-turtle ]
ask turtle tReferenceFrame [ set shape "frame" ]
ask turtle tGyroOrange [ hide-turtle ]
ask turtle tOrangeBall [ show-turtle ]
beep
ifelse LastOutput = ""
[
clear-output
output-type "\n\n\n Click the | Info | link at the top of the screen for more information and instructions.\n"
]
[ output-type LastOutput ]
set Draw_Graph_Paper false ; turn off graph paper
set bNoSplash true
setup-2-Graphics
set bNoSplash false
set bShowMe false
; Only here, show x and y axes alone to match icon on the left.
ask turtle tMarker
[ set color gray
set pen-size 1
repeat 2
[
setxy 4 * ScreenScale 0
set heading 90
pen-down
fd 400 * ScreenScale
pen-up
setxy CenterX -200 * ScreenScale
set heading 0
pen-down
fd 400 * ScreenScale
pen-up
]
]
uPark-tMarker
display ; must call this after <Setup-2-Graphics>
end ; btnShowMe
to btnShowOrbit
if hSim_Running
[ let YNphrase "Clicking [ No ] will destroy the current simulation.\n\n"
set YNphrase word YNphrase "Did you click [ Show This Orbit ] by mistake?\n\n"
display ; always call display before a dialog box
if user-yes-or-no? YNphrase [ stop ]
set bSetUpButtonClicked false ; Don't show next dialog.
]
if bSetUpButtonClicked
[ let YNphrase "You have set up a new simulation.\n\n"
set YNphrase word YNphrase "Did you actually mean to click the\n"
set YNphrase word YNphrase "[Run Simulation] button instead?\n"
set YNphrase word YNphrase "If so, click [ Yes ] and do that.\n\n"
display ; always call display before a dialog box
if user-yes-or-no? YNphrase [ stop ]
]
if R = 0 [ set R 5 ] ; After "Empty space," go to GPS.
set hInteractive false ; reset "Match the image"
set hMatch_Galaxy 1 ; reset "Match the image"
setup-0-Clear&Reset ; calls no-display
setup-1-Initialize ; sets OrbitalRadius and Lock[Control] values
setup-2-Graphics ; calls no-display
drawOrbit ; calls display at end
if LockR = 10 [ if user-yes-or-no? "Is it OK to play an 8-second sound?\n\n" [ sound:play-sound-and-wait "./GSrsc/OneSmallStep8s.au" ] ]
end
to btnSetup ; I want to set up a sim for the scenareo I am looking at, selected with the [Show This Orbit] button.
if hStartupHalt [ user-message "[Halt] clicked during startup; restart required.\n\n" stop ]
if bEarthExists and R != LockR
[ let MsgPhrase "The orbit setting (R) is different from the displayed orbit.\n"
set MsgPhrase word MsgPhrase "To change orbits, first click [ Show This Orbit ].\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set bNoSplash false
stop
]
if hSim_Running and not hInteractive and not (LockChoose_Simulation: = "Empty space")
[ display ; always call display before a dialog box
if not user-yes-or-no? "End the existing simulation and restart immediately?" [ stop ]
]
if Choose_Simulation: != LockChoose_Simulation: [ set Orange_Ball_Mass: 0 ] ; ensures that we dont start a new simulation with mass from a previous simulation
if (Choose_Simulation: = "Circular orbit" or Choose_Simulation: = "Match the image") and Orbit_Stops_At: = "N/A" [ set Orbit_Stops_At: "Never" ] ; "N/A" is not an option for "Circular orbit"
if R = 0 [ set R 5 ] ; After "Empty space," go to GPS.
setup-0-Clear&Reset ; calls no-display
; switches
set bSetUpButtonClicked true
set bResetTimer true
set bNoSplash true
if Choose_Simulation: = "Radial free fall (start here)" [ set bFreeFall true ]
if Choose_Simulation: = "Empty space" [ set bEarthExists false ]
set radial:blue/violet false
set lateral:white/pink false
set corners:red/green false
let AskQuestion true
If bFreeFall and (hUser_Response = 1 or hUser_Response = 3 or hUser_Response = 5 or hUser_Response = 7) [ set AskQuestion false ]
If Choose_Simulation: = "Circular orbit" and (hUser_Response = 2 or hUser_Response = 3 or hUser_Response = 6 or hUser_Response = 7) [ set AskQuestion false ]
If Choose_Simulation: = "Software test" or Choose_Simulation: = "Match the image" [ set AskQuestion false ]
If not bEarthExists and (hUser_Response = 4 or hUser_Response = 5 or hUser_Response = 6 or hUser_Response = 7) [ set AskQuestion false ]
let UseDefault false
if AskQuestion
[ display ; always call display before a dialog box
set UseDefault user-yes-or-no? (word "SIMULATION: " (remove " (start here)" Choose_Simulation:) "\n\nIs this your first time running this simulation choice?\n\n")
]
If Choose_Simulation: = "Software test" or Choose_Simulation: = "Match the image" [ set UseDefault true ] ; always uses default settings, not configurable by the user
; set hMatch_Galaxy 3 ; comment out unless testing angles
ifelse not UseDefault
[ ; user wants to use current settings
if bFreeFall and (R = 1 or R = 3 or R = 10)
[ let MsgPhrase "The altitude of this orbit is too low for this simulation;\n"
set MsgPhrase word MsgPhrase "choose a higher altitude.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set bSetUpButtonClicked false
set bNoSplash false
stop
]
]
[ let MsgPhrase "The recommended default orbit and control\n"
set MsgPhrase word MsgPhrase "settings for this simulation will be set.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set x1 1
if bFreeFall
[ set Synchronous_Rotation false
set R 7
set Orange_Ball_Mass: 0
set Test_Mass_Separation*: 4
set Simulation_Interval: 5
set Orbit_Stops_At: "N/A"
set Frame_Dimension: 100
set Trace_Interval: 5 ; 5 minutes
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set Draw_Graph_Paper true
]
if Choose_Simulation: = "Software test"
[ set R 5
set Frame_Dimension: 150
set MsgPhrase "Each ball’s independent initial velocity is\n"
set MsgPhrase word MsgPhrase "set to place it in an ideal circular orbit;\n"
set MsgPhrase word MsgPhrase "the following are then known sim checks:\n\n"
set MsgPhrase word MsgPhrase "If ↕Synchronous_Rotation is -Off- ,\n"
set MsgPhrase word MsgPhrase "pink & white balls rotate in a circle;\n"
set MsgPhrase word MsgPhrase "top & bottom row trajectories are curvilinear.\n\n"
set MsgPhrase word MsgPhrase "If ↕Synchronous_Rotation is -On- ,\n"
set MsgPhrase word MsgPhrase "pink & white balls are stationary;\n"
set MsgPhrase word MsgPhrase "top & bottom row trajectories are linear.\n\n"
if hTestInit
[ set Synchronous_Rotation false
set Frame_Dimension: 100
set MsgPhrase word MsgPhrase "*** DO NOT terminate test sim manually! ***\n\n"
]
ifelse Synchronous_Rotation
[ set MsgPhrase word MsgPhrase "Status: ↕Synchronous_Rotation is now -On-.\n\n" ]
[ set MsgPhrase word MsgPhrase "Status: ↕Synchronous_Rotation is now -Off-.\n\n" ]
user-message MsgPhrase
set Orange_Ball_Mass: 0
set Test_Mass_Separation*: 10
set Simulation_Interval: 5
set Orbit_Stops_At: "1.00T (360°)"
set Trace_Interval: 10
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set Draw_Graph_Paper true
]
if Choose_Simulation: = "Circular orbit"
[ set Synchronous_Rotation false
set R 5
set MsgPhrase "All nine balls are initially at relative rest;\n"
set MsgPhrase word MsgPhrase "Thus, each ball has the same initial velocity\n"
set MsgPhrase word MsgPhrase "(i.e., the velocity of the reference frame).\n\n"
set MsgPhrase word MsgPhrase "Note that the center orange ball has a mass\n"
set MsgPhrase word MsgPhrase "of ~12.5 tonnes in the default simulation.\n\n"
user-message MsgPhrase
set Orange_Ball_Mass: 6
set Test_Mass_Separation*: 6
set Simulation_Interval: 5
set Orbit_Stops_At: "1.40T"
set Frame_Dimension: 350
set Trace_Interval: 10
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set Draw_Graph_Paper false
set ShowM51 true
]
if Choose_Simulation: = "Match the image"
[ if hMatch_Galaxy = 2 ; M51
[ set Synchronous_Rotation false
set R 5
set Orange_Ball_Mass: 6
set Test_Mass_Separation*: 6
set Simulation_Interval: 10 ; 1.0 second
set Orbit_Stops_At: "Never"
set Frame_Dimension: 350
set Trace_Interval: 10 ; 1.0 minute
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set Draw_Graph_Paper false
]
if hMatch_Galaxy = 1 ; NGC 1097
[ set Synchronous_Rotation false
set R 3
set Orange_Ball_Mass: 1
set Test_Mass_Separation*: 4
set Simulation_Interval: 2 ; 0.2 second
set Orbit_Stops_At: "Never"
set Frame_Dimension: 200
set Trace_Interval: 5 ; 0.5 minutes
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set Draw_Graph_Paper false
]
if hMatch_Galaxy < 1 or hMatch_Galaxy > 2
[ display ; always call display before a dialog box
user-message "Error in <btnSetup>; no such hMatch_Galaxy"
stop
]
]
if not bEarthExists
[ set Synchronous_Rotation false
; 'set R 0' is a general condition for (not bEarthExists); set below
set Orange_Ball_Mass: 3
set Simulation_Interval: 10
set Test_Mass_Separation*: 5
set Orbit_Stops_At: "N/A"
set Frame_Dimension: 100
set Trace_Interval: 3 ; 3 hours
set lateral:white/pink false
set radial:blue/violet false
set corners:red/green false
set Draw_Graph_Paper false
set MsgPhrase "The test masses are given random initial velocities in both\n"
set MsgPhrase word MsgPhrase "direction and speed at up to 90% of escape velocity.\n\n"
set MsgPhrase word MsgPhrase "Click [Set Up Simulation] to refresh a *running* simulation.\n\n"
set MsgPhrase word MsgPhrase "• The orange ball absorbs any collisions with it.\n"
set MsgPhrase word MsgPhrase "• The plotter is inactive for this simulation.\n"
set MsgPhrase word MsgPhrase "• Click [ Show This Orbit ] to return to Earth.\n\n"
set MsgPhrase word MsgPhrase "Ideally, each ball’s Total Energy should remain constant;\n"
set MsgPhrase word MsgPhrase "high periapsis velocity may cause minor simulation error.\n\n"
set MsgPhrase word MsgPhrase "One purpose of this simulation is to demonstrate that the\n"
set MsgPhrase word MsgPhrase "identical code used to the produce the other simulations\n"
set MsgPhrase word MsgPhrase "(see “physics”) yields stable Keplerian elliptical orbits.\n\n"
set MsgPhrase word MsgPhrase "Switch Trace Controls On/Off at will during the simulations.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
]
]
; Always show M51 if the basic default conditions are met.
if R = 5 and Orange_Ball_Mass: = 6 and Test_Mass_Separation*: = 6 and Orbit_Stops_At: = "1.40T" and Frame_Dimension: = 350 and x1 = 1 and Trace_Interval: <= 12 and lateral:white/pink and radial:blue/violet and corners:red/green [ set ShowM51 true ]
; This tracks which of the three basic simulations have been tried using the defaults.
if bFreeFall and hUser_Response != 1 and hUser_Response != 3 and hUser_Response != 5 and hUser_Response != 7 [ set hUser_Response hUser_Response + 1 ]
if Choose_Simulation: = "Circular orbit" and hUser_Response != 2 and hUser_Response != 3 and hUser_Response != 6 and hUser_Response != 7 [ set hUser_Response hUser_Response + 2 ]
if not bEarthExists and hUser_Response != 4 and hUser_Response != 5 and hUser_Response != 6 and hUser_Response != 7 [ set hUser_Response hUser_Response + 4 ]
if bFreeFall
[ ask turtle tPartOfT [ set label "t = N/A" ]
if Synchronous_Rotation
[ display ; always call display before a dialog box
user-message "↕Synchronous_Rotation -On-\nis not meaningful for radial freefall.\n\n"
set Synchronous_Rotation false
]
]
if not bEarthExists
[ set R 0
if Orange_Ball_Mass: = 0
[ let MsgPhrase "For ‘Empty space,’ the minimum allowed value\n"
set MsgPhrase word MsgPhrase "of ||Orange_Ball_Mass is 1.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set Orange_Ball_Mass: 1
]
]
setup-1-Initialize ; sets OrbitalRadius and Lock[Control] values
setup-2-Graphics ; calls no-display
display
set CheckMaxRange 0
set CheckMaxVelocity 0
set CheckMaxRangeColor ""
set CheckMaxVelocityColor ""
set LastReport -1 ; first report at Real-time = 0 != LastReport
ask turtle tOrangeBall [ Turtles-Plot ]
ask radials [ Turtles-Plot ]
ask laterals [ Turtles-Plot ]
ask corners [ Turtles-Plot ]
mainShowMax
let bLabelColorBlack false
if Choose_Simulation: = "Match the image"
[ if not hInteractive ; first pass
[ set hInteractive true
let MsgPhrase "The goal here is to stop the simulation by clicking the\n"
set MsgPhrase word MsgPhrase "mouse (inside the frame) when the trace trails match\n"
set MsgPhrase word MsgPhrase "the complete extent of the galaxy’s spiral arms.\n\n"
set MsgPhrase word MsgPhrase "Note the time required to do so, expressed as a fraction\n"
set MsgPhrase word MsgPhrase "(n) of the orbital period (“t = nT”) in green.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
]
]
ask turtle tMessage
[ set color black
set label-color orange
ifelse LockOrange_Ball_Mass: > 0
[ ifelse LockChoose_Simulation: = "Empty space"
[ ifelse bNotHD
[ set label "Interaction is exclusively with the mass of the orange ball;"
setxy (229) (- 138)
]
[
set label "Interaction is exclusively with the mass of the orange ball; no interactions occur between any of the 1-gram test masses."
setxy (384) (- 194)
]
]
[ ifelse bNotHD
[ set label "Interaction is exclusively with the mass of the Earth and the orange ball;"
setxy (215) (- 138)
]
[
set label "Interaction is exclusively with the mass of the Earth and the orange ball; no interactions occur between the eight 1-gram test masses."
setxy (395) (- 194)
]
]
]
[
ifelse bNotHD
[ set label "Interaction is exclusively with the mass of the Earth;"
ifelse bLabelColorBlack [ set color 7 set label-color black ][ set label-color 86 ] ; same as GM label
setxy (156) (- 138)
]
[
set label "Interaction is exclusively with the mass of the Earth; no interactions occur between the nine 1-gram test masses."
ifelse bLabelColorBlack [ set color 7 set label-color black ][ set label-color 86 ] ; same as GM label
setxy (369) (- 194)
]
]
show-turtle
]
if bNotHD
[ ask turtle tMessage2
[ set color black
set label-color orange
ifelse LockOrange_Ball_Mass: > 0
[ ifelse LockChoose_Simulation: = "Empty space"
[ set label "no interactions occur between any of the 1-gram test masses."
setxy (242) (- 146)
]
[ set label "no interactions occur between the eight 1-gram test masses."
setxy (184) (- 146)
]
]
[
set label "no interactions occur between the nine 1-gram test masses."
ifelse bLabelColorBlack [ set color 7 set label-color black ][ set label-color 86 ] ; same as GM label
setxy (181) (- 146)
]
show-turtle
]
]
mainOutputHeader
set bShowOrbitClicked false
end ; btnSetup
to btnRun
; PART 1: reasons to stop running
;=========================================================================================================================================================================================
if hInteractive and Mouse-down?
[ display ; always call display before a dialog box
let result "OK"
if hMatch_Galaxy = 2 ; M51
[ if OrangeMyPhaseDeg < 475 [ set result "TooSoon" ]
if OrangeMyPhaseDeg > 520 [ set result "TooLate" ]
]
if hMatch_Galaxy = 1 ; NGC 1097
[ if OrangeMyPhaseDeg < 325 [ set result "TooSoon" ]
if OrangeMyPhaseDeg > 370 [ set result "TooLate" ]
]
let value repNumber (Real-time / OrbitalPeriod) 2
if result = "test" [ user-message (word "You stopped at OrangeMyPhaseDeg: " repnumber OrangeMyPhaseDeg 2 "\n\nContinue test.\n\n") ]
if result = "TooSoon" [ user-message "It seems that you clicked too soon;\nthe galaxy’s arms extend beyond this point.\n\n" ]
if result = "TooLate"
[ let MsgPhrase "It seems that you clicked too late;\n"
set MsgPhrase word MsgPhrase "the galaxy’s arms don’t extend this far.\n\n"
set MsgPhrase word MsgPhrase "You will need to repeat this simulation.\n\n"
user-message MsgPhrase
set hInteractive false
set hSim_Running false
set bEndOfSimuation true
set bSetUpButtonClicked false
stop
]
if result = "OK"
[ let GalaxiesToShow 2
let MsgPhrase (word "You stopped at t ≈ " value "T.\n\n")
if hMatch_Galaxy < GalaxiesToShow [ set MsgPhrase word MsgPhrase "Let’s do the same thing with another galaxy…\n\n" ]
user-message MsgPhrase
ifelse hMatch_Galaxy < GalaxiesToShow
[ set hMatch_Galaxy hMatch_Galaxy + 1
no-display
set R LockR ; Don't let a disallowed change in the R control cause a dialog box.
btnSetup ; hInteractive = true supresses dialog boxes and last display
]
[
set MsgPhrase "KEY CONCEPT:\n"
set MsgPhrase word MsgPhrase "A larger fraction of an orbit produces a longer spiral.\n"
set MsgPhrase word MsgPhrase "---------------------------------------------\n\n"
set MsgPhrase word MsgPhrase "For elliptic orbits, T = 2⋅π⋅Sqrt[ a^3 / μ ];\n"
set MsgPhrase word MsgPhrase "this implies that T is sensitive to the\n"
set MsgPhrase word MsgPhrase "semi-major axis of the orbit (a).\n\n"
set MsgPhrase word MsgPhrase "If, contrary to conventional wisdom, spiral galaxy\n"
set MsgPhrase word MsgPhrase "morphology and rotation curves are caused by the\n"
set MsgPhrase word MsgPhrase "modeled phenomenon (i.e., systemic galaxy orbits),\n"
set MsgPhrase word MsgPhrase "then the plausibility of constraints on the age of\n"
set MsgPhrase word MsgPhrase "galaxies imposed by the “Big Bang” standard\n"
set MsgPhrase word MsgPhrase "cosmological model must be reconsidered.\n\n"
set MsgPhrase word MsgPhrase "See:\n"
set MsgPhrase word MsgPhrase "Nature 487, 338 (2012); < arxiv.org/abs/1207.4196 >.\n"
set MsgPhrase word MsgPhrase "Also see this PDF: < SensibleUniverse.com/Cosmos >.\n\n"
user-message MsgPhrase
set hInteractive false
set hMatch_Galaxy 1
set hSim_Running false
set bEndOfSimuation true
set bSetUpButtonClicked false
stop
]
]
]
if not bSetUpButtonClicked ; We are prepared to run.
[ beep
display ; always call display before a dialog box
user-message "Please first set up a new simulation.\n\n"
set hSim_Running false
stop
]
let SkipTicks 20
if LockR = 9 [ set SkipTicks 1000 ] ; Lunar orbit, so do things 50x faster
ifelse ticks mod 20 = 0 [ display ][ no-display ] ; a higher value speeds up the simulation
if bShowOrbitClicked
[ set bShowOrbitClicked false
set bEndOfSimuation true
set bSetUpButtonClicked false
set hSim_Running false
stop
]
if bEndOfSimuation
[ beep
display ; always call display before a dialog box
user-message "Cannot run simulation; first click [ Set Up Simulation ].\n\n"
set hSim_Running false
stop
]
if bEarthExists and OrangeMyPhaseDeg >= AutoStopAngle
[ ifelse bEarthExists and ticks > 0 [ mainOutputStatus ][ mainOutputStatus2 ] ; Send a final status report to output.
beep
display ; always call display before a dialog box
user-message "The simulation has stopped at the Orbit_Stops_At↓ value.\n\n"
if ShowM51
[ import-drawing "./GSrsc/M51.png"
ask turtle tReferenceFrame [ hide-turtle ]
ask OrbitData [ hide-turtle ]
let OutputPhrase "=============================================================================================================\n"
set OutputPhrase word OutputPhrase "In physics, the purpose of a so-called “toy model” (right) is to demonstrate fundamental physical principles\n"
set OutputPhrase word OutputPhrase "at work in real, complex physical systems (e.g., a galaxy of billions of interacting stars: M51 on the left).\n"
set OutputPhrase word OutputPhrase "In addition to the obvious similarity in the spiral morphology, also note the periodic widening and narrowing\n"
set OutputPhrase word OutputPhrase "of the spiral arms, which is apparent in both the model and the real galaxy, and that the Speed versus Radius\n"
set OutputPhrase word OutputPhrase "graph shows linearly-increasing test-mass speed (i.e., tangential velocity) as a function of radial distance.\n"
set OutputPhrase word OutputPhrase "This implies that spiral galaxies, which are not similarly isolated, cannot be expected to exhibit a velocity\n"
set OutputPhrase word OutputPhrase "profile similar to the Solar System, where the nearest star is ~9000 times the orbital radius of Neptune.\n"
beep
output-type OutputPhrase
let MsgPhrase "“We are to admit no more causes of natural things\n"
set MsgPhrase word MsgPhrase " than such as are both true and sufficient to explain\n"
set MsgPhrase word MsgPhrase " their appearances.” – Isaac Newton\n\n"
set MsgPhrase word MsgPhrase "AFTER you click [ OK ]:\n"
set MsgPhrase word MsgPhrase "Please read the important information newly posted\n"
set MsgPhrase word MsgPhrase "to the general message box.\n\n"
user-message MsgPhrase
]
if Choose_Simulation: = "Software test" and hTestInit
[ set hTestInit false
set Synchronous_Rotation true
let MsgPhrase "↕Synchronous_Rotation has been switched -On-.\n\n"
set MsgPhrase word MsgPhrase "Click [ Set Up Simulation ] and then run the\n"
set MsgPhrase word MsgPhrase "the second phase of the test [ Run Simulation ].\n\n"
user-message MsgPhrase
]
set bShowOrbitClicked true
set bEndOfSimuation true
set bSetUpButtonClicked false
set hSim_Running false
stop
]
if not mainAny-Balls_left? ; All balls crashed into the orange ball.
[ ifelse bEarthExists and ticks > 0 [ mainOutputStatus ][ mainOutputStatus2 ] ; Send a final status report to output.
beep
display ; always call display before a dialog box
let GoAgain false
ifelse LockChoose_Simulation: = "Empty space"
[ let YNphrase "All the other test masses have been absorbed\n"
set YNphrase word YNphrase "by the orange ball; the simulation is over.\n\n"
set YNphrase word YNphrase "Run another? (new random intitial velocities)\n\n"
set GoAgain user-yes-or-no? YNphrase
]
[ let MsgPhrase "All the other test masses have been absorbed\n"
set MsgPhrase word MsgPhrase "by the orange ball; the simulation is over.\n\n"
user-message MsgPhrase
]
ifelse GoAgain
[
set R LockR ; Don't let a disallowed change in the R control cause a dialog box.
btnSetup ; "Empty space" supresses dialog box.
]
[
set bShowOrbitClicked true
set bEndOfSimuation true
set bSetUpButtonClicked false
set hSim_Running false
stop
]
]
; The radial free fall has ended when the frame drops below R = 6700 km; last report before stop.
if bEarthExists and OrangeMyRadius < (6700 * 1000) and bFreeFall
[ ask turtle tOrangeBall
[ ; update the left panel display value
let NewRadius My-py
let Runits " km"
let NewRadiusShow repNumber (NewRadius / 1000) 3
if NewRadius / 1000 < 10000 [ set Runits " km " ]
set NewRadiusShow (word "R = " NewRadiusShow Runits)
ask turtle tOrbitalRadius [ set label NewRadiusShow ]
ifelse bEarthExists and ticks > 0 [ mainOutputStatus ][ mainOutputStatus2 ] ; Send a final status report to output.
let OutputPhrase " # The simulation stopped; altitude is too low (approaching the atmosphere). #\n\n"
set OutputPhrase word OutputPhrase " NOTE: This well-known gravitational tidal force phenomenon is commonly called the “spaghetti effect.”\n"
set OutputPhrase word OutputPhrase " ***********************************************************************************************************\n"
set OutputPhrase word OutputPhrase " * NEXT: Add mass to the orange ball (the selector has a log scale) and observe its gravitational effect *\n"
set OutputPhrase word OutputPhrase " * on the dynamics of the other eight colored balls (i.e., 1-gram test masses). Afterwards, change *\n"
set OutputPhrase word OutputPhrase " * Choose_Simulation↓ to “Circular orbit” and initially run the recommended default simulation. *\n"
set OutputPhrase word OutputPhrase " ***********************************************************************************************************\n"
beep
output-type OutputPhrase
]
display
set bShowOrbitClicked true
set bEndOfSimuation true
set bSetUpButtonClicked false
set hSim_Running false
stop
]
; PART 2: Controls cannot change during run.
;=========================================================================================================================================================================================
if Synchronous_Rotation != LockSynchronous_Rotation
[ let MsgPhrase "You cannot change ↕Synchronous_Rotation\n"
set MsgPhrase word MsgPhrase "during a simulation.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
set Synchronous_Rotation LockSynchronous_Rotation
]
if LockR != R
[ display ; always call display before a dialog box
user-message "You cannot change the orbit during a simulation.\n\n"
set R LockR
]
if LockChoose_Simulation: != Choose_Simulation:
[ display ; always call display before a dialog box
user-message "You cannot change Choose_Simulation↓ during a simulation.\n\n"
set Choose_Simulation: LockChoose_Simulation:
]
if Orange_Ball_Mass: != LockOrange_Ball_Mass:
[ display ; always call display before a dialog box
user-message "You cannot change ||Orange_Ball_Mass during a simulation.\n\n"
set Orange_Ball_Mass: LockOrange_Ball_Mass:
]
if Simulation_Interval: != LockSimulation_Interval:
[ display ; always call display before a dialog box
user-message "You cannot change ||Simulation_Interval\nduring a simulation.\n\n"
set Simulation_Interval: LockSimulation_Interval:
]
if Orbit_Stops_At: != LockOrbit_Stops_At:
[ display ; always call display before a dialog box
user-message "You cannot change Orbit_Stops_At↓ during a simulation.\n\n"
set Orbit_Stops_At: LockOrbit_Stops_At:
]
if Frame_Dimension: != LockFrame_Dimension: or x1 != Lockx1
[ display ; always call display before a dialog box
user-message "You cannot change ||Frame_Dimension during a simulation.\n\n"
set Frame_Dimension: LockFrame_Dimension:
set x1 Lockx1
]
if Trace_Interval: != LockTrace_Interval:
[ display ; always call display before a dialog box
user-message "You cannot change ||Trace_Interval during a simulation.\n\n"
set Trace_Interval: LockTrace_Interval:
]
; PART 3: initialize and report (btnRun)
;=========================================================================================================================================================================================
set bSetUpButtonLocked true ; We are running, so don't let the user click the [ Set Up Simulation ] button.
if bResetTimer ; resets once at tick 0 to initialize {Real-time} to 0 and to recod how long we have been running the sim via {Run-time}
[ reset-timer
set Real-time 0
set bResetTimer false
set hSim_Running true
output-type "\n" ; Skip a line between the header and the first status report.
]
; Update the two timers and the simulation speed indicator at the top of the Dashboard
set Real-timeShow uCenterText (repHumanTime Real-time) 20 ; starts off at 00:00:00 at tick 0
set Run-time timer
set Run-timeShow uCenterText22 (repHumanTime Run-time)
if ticks mod 2500 = 0
[ if ticks > 0 [ set SimulationSpeed uCenterText22 (precision ((2500 * LockTimePerTick) / (Run-time - lastRun-time)) 0) ]
set LastRun-time Run-time
]
; Based on the real-time, we know the precide phase angle of the orange ball {FrameIdealTheta} and we report it as {tPartOfT}.
if bEarthExists
[ set FrameIdealTheta (Real-time / OrbitalPeriod) * 360
if not bFreeFall
[ let value repNumber (Real-time / OrbitalPeriod) 3
ask turtle tPartOfT [ set label (word "t = " value "T") ]
]
]
; Send a status report to output.
if LockTrace_Interval: > 0
[ if (int(Real-time) != LastReport) and (remainder int(Real-time) (LockTrace_Interval: * TraceSecondsMultiplier) = 0) [ ifelse bEarthExists [ mainOutputStatus ][ mainOutputStatus2 ] ] ]
; PART 4: Simulation (btnRun)
;=========================================================================================================================================================================================
; After reporting initial conditions at time 0, the first pass occurs at 1 * LockTimePerTick
set Real-time (ticks + 1) * LockTimePerTick
; What happened to the orange ball over the last tick of time?
ask turtle tOrangeBall ; Always update the orange ball first so that other balls can get corrected position (or velocity for free fall).
[ ifelse bEarthExists
[ physics-0-sequence ]; physics-5-properties sets the set of OrangeMy-<properties> and also sets DistanceChange & Arcseconds
[
set DistanceChange uCenterText22 "N/A"
set Arcseconds uCenterText22 "N/A"
ask turtle tOrbitalSpeedSim [set label "0.00000 km/s (sim)" ]
]
]
; end of "What happened to the orange ball?"
; Report the speed of the orange ball in km/s {kps}.
let kps precision (sqrt( OrangeMy-vx ^ 2 + OrangeMy-vy ^ 2) / 1000) 5
if kps > 10 [ set kps precision kps 4 ]
let kpsAlpha word kps ""
let StringLength length kpsAlpha
while [StringLength < 7 ]
[ set kpsAlpha word kpsAlpha "0"
set StringLength length kpsAlpha
]
ask turtle tOrbitalSpeedSim [ set label (word kpsAlpha " km/s (sim)") ]
; Since we know where the orange ball is, we know where the frame is and we plot its progress.
if bEarthExists
[ ask turtle tReferenceFrame
[ let TimeDelta 0
if LockTrace_Interval: > 0 [ set TimeDelta remainder int(Real-time) (LockTrace_Interval: * TraceSecondsMultiplier) ]
ifelse TimeDelta = 0 [ pen-down ][ pen-up ]
let fx (OrbitRadius * OrangeMyRadius / OrbitalRadius) * cos repMathAngle OrangeMyPhaseDeg - CenterX
let fy (OrbitRadius * OrangeMyRadius / OrbitalRadius) * sin repMathAngle OrangeMyPhaseDeg
if LockSynchronous_Rotation [ set heading OrangeMyPhaseDeg ]
setxy fx fy
]
]
; What happened to the other balls over the last tick of time?
set CheckMaxRange 0
set CheckMaxVelocity 0
; sorting makes MaxVelocity and MaxRange favor red/green/blue/white
; ask <breed> is not deterministic, so we need to sort
foreach sort radials
[ ask ? [ physics-0-sequence Turtles-Plot ] ]
foreach sort laterals
[ ask ? [ physics-0-sequence Turtles-Plot ] ]
foreach sort corners
[ ask ? [ physics-0-sequence Turtles-Plot ] ]
mainShowMax
; end of "What happened to the other balls"
tick ; Advance the time for the next pass.
end ;btnRun
to btnErase
if Real-timeShow = 0 [ user-message "Nothing to erase.\n\n" stop ]
let YNphrase "Clear all current trace trails?\n\n"
set YNphrase word YNphrase "This wll also activate changes to ↕Draw_Graph_Paper.\n\n"
display ; always call display before a dialog box
if user-yes-or-no? YNphrase
[ clear-drawing
setup-2-Graphics ; calls no-display
display
let OutputPhrase (word "\n\n\n*** TRACE TRAILS CLEARED AT " (remove " " Real-timeShow) " REAL-TIME ***\n\n\n\n\n")
beep
output-type OutputPhrase
]
end
to btnSave
if hStartupHalt [ user-message "[ Halt ] clicked during startup; restart required.\n\n" stop ]
let NoFileName true
let DoWrite false
let FileName ""
display
while [ NoFileName = true ]
[ display ; always call display before a dialog box
set FileName user-new-file
ifelse FileName = false [ set NoFileName false ]
[ let txtFile word FileName "-GravitySim.png"
ifelse file-exists? txtFile
[ let YNphrase "This file name already exists and will be overwritten.\n"
set YNphrase word YNphrase "Use a different file name? [Yes]\n"
set YNphrase word YNphrase "CLICKING [ No ] HERE WILL OVERWRITE EXISTING FILE.\n"
set YNphrase word YNphrase "Click [ Yes ] to use a different file name (SAFE default).\n\n"
display ; always call display before a dialog box
if not user-yes-or-no? YNphrase
[ set NoFileName false set DoWrite true ]
]
[ set NoFileName false set DoWrite true ]
]
]
if DoWrite
[ ; Put a copyright notice and URL on the exported view
ask turtle tMessage
[ set color black
setxy (- 131) (- 194)
set label "Copyright ©2012 Alexander F. Mayer < http://GravitySim.net >"
show-turtle
]
export-view word FileName "-GravitySim.png"
uPark-tMessage
display ; always call display before a dialog box
if user-yes-or-no? "Add a complete interface image?\n\n" [ export-interface word FileName "-interface.png" ]
if user-yes-or-no? "Include the output text file?\n(This file is encoded UTF-8.)\n\n"
[ let txtFile word FileName "-output.txt"
export-output txtFile
file-open txtFile
file-print ""
file-print ""
file-print "GravitySim application ( http://GravitySim.net ) Copyright ©2012 Alexander F. Mayer"
file-close
]
]
end ; btnSave
;=========================================================================================================================================================================================
; startup and setup
;=========================================================================================================================================================================================
; runs automatically at startup and initializes the application
to startup
; control defaults
set hTestInit true ; switch hidden under output
set hStartupHalt true ; switch hidden under output
set hSim_Running false ; switch hidden under output
set hInteractive false ; switch hidden under output
set hMatch_Galaxy 1 ; slider (1 – 10) hidden under output
set hUser_Response 20 ; slider (0 – 20) hidden under output (This setting means we are staring up and want the Startup splash screen.)
set Synchronous_Rotation false
set R 3 ; HST
set LockR 3 ; must set as this is the current orbit
set Choose_Simulation: "Radial free fall (start here)"
set Orange_Ball_Mass: 0
set Test_Mass_Separation*: 5
set Simulation_Interval: 5
set Orbit_Stops_At: "1.00T (360°)"
set Frame_Dimension: 50
set x1 1
; set Trace_Interval: (set automatically for choice of R)
set lateral:white/pink true
set radial:blue/violet true
set corners:red/green true
set BIG false
set Draw_Graph_Paper true
set bShowOrbitClicked true ; supress dialog box
set bSetUpButtonClicked false ; supress dialog box
btnShowOrbit
let MsgPhrase ""
if false ; I like it, but probably not for everyone. Removed as of v 1.5 (for people who do not edit this line of code).
[
set MsgPhrase "In memoriam:\n"
set MsgPhrase word MsgPhrase "Sir Arthur C. Clarke (1917 – 2008)\n\n"
set MsgPhrase word MsgPhrase "Please click [ OK ] only when\n"
set MsgPhrase word MsgPhrase "the sound ends (40 seconds) …\n"
set MsgPhrase word MsgPhrase "Do not click [ Halt ]."
let YNphrase "These dialog boxes can be dragged anywhere.\n\n"
set YNphrase word YNphrase "Play the startup sound? (40 seconds)\n"
set YNphrase word YNphrase "Do not click [ Halt ]."
if user-yes-or-no? YNphrase [ sound:play-sound-and-wait "./GSrsc/astronaut40s.au" user-message MsgPhrase ]
]
set MsgPhrase "Welcome to GravitySim!\n\n"
set MsgPhrase word MsgPhrase "• If running the app locally (i.e., not in a browser):\n"
set MsgPhrase word MsgPhrase " – Java heap size *must* be set per the READ ME file.\n"
set MsgPhrase word MsgPhrase " – Adjust interface to your monitor with the Zoom menu.\n"
set MsgPhrase word MsgPhrase " (Zoom is not available in the Internet-based applet.)\n\n"
set MsgPhrase word MsgPhrase "• Please note that the setting indicators under the slide\n"
set MsgPhrase word MsgPhrase " controls will reflect any control changes only *after*\n"
set MsgPhrase word MsgPhrase " you click the [ Set Up Simulation ] button.\n\n"
set MsgPhrase word MsgPhrase "• American notation is used; a period is a decimal mark\n"
set MsgPhrase word MsgPhrase " (π = 3.14159…) and a comma is a digit group separator\n"
set MsgPhrase word MsgPhrase " (100 × 100 = 10,000).\n\n"
set MsgPhrase word MsgPhrase "• Whenever new information is posted to the general\n"
set MsgPhrase word MsgPhrase " message box, you will hear an alert beep.\n\n"
set MsgPhrase word MsgPhrase " Do not click [ Halt ]."
user-message MsgPhrase
let OutputPhrase "\n"
set OutputPhrase word OutputPhrase " The location of the NASA Jet Propoulsion Laboratory (JPL) in Pasadena, California is shown on the globe.\n"
set OutputPhrase word OutputPhrase " The appearance of the distinctive JPL logo does not construe that this software is in any way associated\n"
set OutputPhrase word OutputPhrase " with JPL. It does, however, reflect my respect for the JPL Team, whose various scientific missions serve\n"
set OutputPhrase word OutputPhrase " to benefit all mankind. I encourage exploration of the JPL website < www.jpl.nasa.gov > and for citizens\n"
set OutputPhrase word OutputPhrase " of the U.S.A. to e-mail their Congressional representatives in support of JPL’s annual budget. –A. Mayer\n\n"
output-type OutputPhrase
output-type "=============================================================================================================\n"
set LastOutput "\n"
set LastOutput word LastOutput " If you are new to GravitySim, first click the [ ← Show Me ] button at the top left of the screen.\n"
set LastOutput word LastOutput " Afterwards, click the | Info | link at the top of the screen for more information and instructions.\n"
set LastOutput word LastOutput "\n"
set LastOutput word LastOutput " NOTE: Lunar and Solar gravity are ignored; the Earth is treated as an idealized, isolated point mass.\n"
set LastOutput word LastOutput " -----------------------------------------------------------------------------------------------\n\n"
beep
output-type LastOutput
set hStartupHalt false ; False means the user did not click Halt during startup and therefore saw all nessessary messages and output.
set MsgPhrase "AFTER you click [ OK ]:\n\n"
set MsgPhrase word MsgPhrase "If running the application locally:\n"
set MsgPhrase word MsgPhrase "Select menu item [Tools] → 'Hide Command Center'.\n\n"
set MsgPhrase word MsgPhrase "Please read the entire contents of the general message\n"
set MsgPhrase word MsgPhrase "box (below photo on the right); you will need to scroll up.\n\n"
set MsgPhrase word MsgPhrase "Thank you.\n\n"
display ; always call display before a dialog box
user-message MsgPhrase
end ; startup
to setup-0-Clear&Reset
no-display
clear-all ; clears all global variables and kills all turtles!
set bNotHD false ; true if this is not the HD version
set ScreenScale 1
set Screen_dx 0
set Screen_dy 0
set OrbitRadius 180
set CenterX 204
set GyroOffset 100
if bNotHD [ set ScreenScale 0.75 set Screen_dx 101 set Screen_dy 50 set OrbitRadius 135 set CenterX 153 set GyroOffset 75 ]
set bShowOrbitClicked true ; we are going to display something
set hSim_Running false
set LockR R ; the current orbit
; other switches
set bShowMe false ; tells setup-2-Graphics that it was called by btnShowMe, not by startup or btnReset
set bNoSplash false ; tells setup-2-Graphics not to use splash screens — we about to run a simulation
set bSetUpButtonLocked false ; when running (= true), user cannot click the setup button before a reset
set bSetUpButtonClicked false ; btnShowMe should not work afterwards
set bFreeFall false ; user chose "Radial free fall" simulation
set bEarthExists true ; if false, user chose "Empty space (no Earth)" simulation
set bEndOfSimuation false ; Orbit_Stops_At: was reached
set bResetTimer false ; used in btnRun to start the Run-time timer
set bPreciseColors false ; if false (default) "lime" is reported as "green"; "sky" is reported as "blue"
set ShowM51 false ; compare simulation to M51
set PadLeftSpaces 0 ; used by repNumber, which pads PadLeftSpaces to the left of numbers
set LastOutput ""
set LastAlert ""
import-drawing "./GSrsc/Columbia.png" ; screen-wide supercomputer
; ================================================================================================================================
set-default-shape turtles "circle"
let ball-diameter round (400 / Frame_Dimension:) ; pixels per 1-meter-diameter test-mass locator
if ball-diameter < 1 [ set ball-diameter 1 ]
; ================================================================
; label turtles
; ================================================================
create-OrbitData 1
[ set color black
set size 4
setxy (- 330 + Screen_dx) (193 - Screen_dy) ; top left corner
set label "v = 0.00000 km/s (calc)"
set label-color yellow
]
set tOrbitalSpeedCalc (count turtles - 1)
create-OrbitData 1
[ set color black
set size 4
setxy (- 330 + Screen_dx) (183 - Screen_dy) ; top left corner
set label "0.00000 km/s (sim)"
set label-color lime
]
set tOrbitalSpeedSim (count turtles - 1)
; ================================================================
create-OrbitData 1
[ set color black
set size 4
setxy (- 341 + Screen_dx) (- 194 + Screen_dy) ; bottom left corner (left panel)
; set label "R = "
set label-color orange
]
set tOrbitalRadius (count turtles - 1)
create-OrbitData 1
[ set color black
set size 4
setxy (- 9) (- 194 + Screen_dy) ; bottom right corner (left panel)
; set label "GM = n km^3 / s^2"
set label-color 86
]
set tGM (count turtles - 1)
create-OrbitData 1
[ set color black
set size 4
setxy (- 9) (193 - Screen_dy); top right corner (left panel)
; set label "T = "
set label-color yellow
]
set tOrbitalPeriod (count turtles - 1)
crt 1 ; We don't include this one in "OrbitData," because we want to show how many turns it took to create the spiral.
[ set color black
set size 4
setxy (- 9) (183 - Screen_dy) ; top left corner (left panel)
set label "t = 0.000T"
set label-color lime
]
set tPartOfT (count turtles - 1)
; ================================================================
create-OrbitData 1
[ set color black
set size 4
setxy (- 226 + Screen_dx / 2) (193 - Screen_dy) ; top middle (left panel)
set label "m = 1 g"
set label-color orange
]
set tOrangeMass (count turtles - 1)
create-OrbitData 1
[ set color black
set size 4
setxy (- 140 + Screen_dx / 2) (193 - Screen_dy) ; top middle (left panel)
set label "Δt = "
set label-color orange
]
set tTraceInterval (count turtles - 1)
; ================================================================
; reference frame turtle (created first, thus *behind* "little gyros")
; ================================================================
crt 1
[ set shape "frame" ; set by setup-2-Graphics to "frame-small" for ISS orbit (looks better than shrinking the original with "set size")
set size 20 * ScreenScale ; permanent size
set color 26 ; the pen color, not the color of anything that shows
ifelse BIG [ set pen-size 3 ][ set pen-size 2 ] ; small (but not tiny) dots
set heading 0 ; parked heading
setxy (- CenterX) OrbitRadius ; permanent parking spot
]
set tReferenceFrame (count turtles - 1)
; ================================================================
; gyro turtles
; ================================================================
let angle 2 ; the angle to displace the little "gyros" inside the orbiting frame
crt 1
[ set color red
set size 3
set heading 0
setxy (- CenterX + OrbitRadius * sin (- angle)) (0 + OrbitRadius * cos (- angle)) ; permanent parking spot
set MyPhaseInit (- angle) ; used in {drawOrbit} routine to orbit it in sycnch with tReferenceFrame
set MyPhaseDeg (- angle) ; not used
hide-turtle
]
set tLittleGyroRed (count turtles - 1)
crt 1
[ set color lime
set size 3
set heading 0
setxy (- CenterX + OrbitRadius * sin angle) (0 + OrbitRadius * cos angle) ; permanent parking spot
set MyPhaseInit angle ; used in {drawOrbit} routine to orbit it in sycnch with tReferenceFrame
set MyPhaseDeg angle ; not used
hide-turtle
]
set tLittleGyroGreen (count turtles - 1)
crt 1
[ set color orange
set shape "gyro"
set size 40 * ScreenScale
set heading 0
setxy CenterX 0 ; permanent parking spot
hide-turtle
]
set tGyroOrange (count turtles - 1)
crt 1
[ set color red
set shape "gyro"
set size 43 * ScreenScale
set heading 0
setxy (CenterX - GyroOffset) 0 ; permanent parking spot
hide-turtle
]
set tGyroRed (count turtles - 1)
crt 1
[ set color lime
set shape "gyro"
set size 43 * ScreenScale
set heading 0
setxy (CenterX + GyroOffset) 0 ; permanent parking spot
hide-turtle
]
set tGyroGreen (count turtles - 1)
; ================================================================
; simulation turtles
; ================================================================
crt 1
[ set color orange ]
set tOrangeBall (count turtles - 1)
; ================================================================
let BallPenSize 3
if BIG [set BallPenSize 4 ]
if x1 = 10 [
ifelse BIG [ set BallPenSize 2 ] [ set BallPenSize 1 ]
]
create-corners 1
[ set color red
set pen-size BallPenSize
hide-turtle
]
set tRedBall_TL (count turtles - 1)
create-corners 1
[ set color lime
set pen-size BallPenSize
hide-turtle
]
set tGreenBall_TR (count turtles - 1)
create-corners 1
[ set color magenta
set pen-size BallPenSize
hide-turtle
]
set tMagentaBall_BL (count turtles - 1)
create-corners 1
[ set color yellow
set pen-size BallPenSize
hide-turtle
]
set tYellowBall_BR (count turtles - 1)
; ================================================================
create-radials 1
[ set color sky
set pen-size BallPenSize
hide-turtle
]
set tBlueBall_TC (count turtles - 1)
create-radials 1
[ set color violet
set pen-size BallPenSize
hide-turtle
]
set tVioletBall_BC (count turtles - 1)
; ================================================================
create-laterals 1
[ set color white
set pen-size BallPenSize
hide-turtle
]
set tWhiteBall_MR (count turtles - 1)
create-laterals 1
[ set color pink
set pen-size BallPenSize
hide-turtle
]
set tPinkBall_ML (count turtles - 1)
; ================================================================
; utility turtles
; ================================================================
crt 1
[ set color black
hide-turtle
]
set tMarker (count turtles - 1)
crt 1
[ set color black
hide-turtle
]
set tMessage (count turtles
- 1)
crt 1
[ set color black
hide-turtle
]
set tMessage2 (count turtles - 1)
; hide turtles and reset-ticks
; ================================================================================================================================
ask turtle tReferenceFrame [ hide-turtle ]
ask OrbitData [ hide-turtle ]
ask turtle tPartOfT [ hide-turtle ]
uPark-tMarker
uPark-tMessage
reset-ticks ; reset to time zero; must go last because it activates the plot area, which needs {bEarthExists}
end ; setup-0-Clear&Reset
to setup-1-Initialize
; Did the user choose a valid setting of the ||R slider?
if R != 0 and R != 1 and R != 3 and R != 5 and R != 7 and R != 9 and R != 10 ; zero is for empty space
[ let phrase (word "The orbit setting is set between options.\nChoices for are limited to:")
display ; always call display before a dialog box
let choice read-from-string first (user-one-of phrase [ "1 – International Space Station orbit (ISS)" "2 – Hubble Space Telescope orbit (HST)" "3 – Global Positioning System orbit (GPS)" "4 – Geostationary orbit (Geo)" "5 – Mean Lunar orbit (Moon)" "6 – Lunar Reconnaissance Orbiter (◗)" ])
if choice = 1 [ set R 1 ]
if choice = 2 [ set R 3 ]
if choice = 3 [ set R 5 ]
if choice = 4 [ set R 7 ]
if choice = 5 [ set R 9 ]
if choice = 6 [ set R 10 ]
no-display
]
; standard near-Earth values (Geo and Moon different)
set Time_IntervalMultiplier 0.1 ; 1 second max.
set TraceSecondsMultiplier 6
; Set {OrbitalPeriod}, the fundamental physical parameter determining the orbital parameters based on ||R slider setting.
; {Trace_Interval:} spaces the dots in a meaningful way for the default display.
ifelse R = 0 ; "Empty space" simulation
[ set OrbitalPeriod 0
set Time_IntervalMultiplier 1 ; 10 seconds max.
set TraceSecondsMultiplier 3600
]
[
ifelse R = 1
[ set OrbitalPeriod 92.8588 * 60 ; Nominal ISS value
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 30 ] ; [Show This Orbit] button clicked
]
[
ifelse R = 3
[ set OrbitalPeriod 95.8146 * 60 ; Nominal HST value
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 30 ] ; [Show This Orbit] button clicked & * startup *
]
[
ifelse R = 5
[ set OrbitalPeriod 717.9882 * 60 ; Nominal GPS value
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 30 ]
set TraceSecondsMultiplier 60
]
[
ifelse R = 7
[ set OrbitalPeriod 23.9344696 * 3600 ; sidereal day in seconds (Geostationary orbit)
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 60 ]
set TraceSecondsMultiplier 60
]
[
ifelse R = 9
[ set OrbitalPeriod 27.3217 * 86400 ; Lunar revolution period in seconds
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 24 ]
if Frame_Dimension: < 100 and bSetupButtonClicked
[ display ; always call display before a dialog box
user-message "The minimum frame size for “Moon” is 100 m.\n\n"
set Frame_Dimension: 100 ; Otherwise, balls go off-screen in "Radial free fall".
]
set TraceSecondsMultiplier 3600
set Time_IntervalMultiplier 1 ; 10 seconds max.
]
[
ifelse R = 10
[ set OrbitalPeriod 2 * pi * sqrt(1788387.1464 ^ 3 / 4902.798E9) ; parameter sources: LRO_Mission_Baseline_Ephemeris_v11_file2.txt (avg value of a) & JPL HORIZONS (GM)
if not bShowMe and not bFreeFall and not bSetupButtonClicked [ set Trace_Interval: 4 ]
set TraceSecondsMultiplier 6
]
[
let MsgPhrase "Error in setup-1-Initialize;\n"
set MsgPhrase word MsgPhrase "no such orbital radius (R) setting for Earth."
display
user-message MsgPhrase
stop
]
]
]
]
]
]
]
if not bSetUpButtonClicked and not (hUser_Response = 20)
[ ; make it pretty
set Draw_Graph_Paper false
ask turtle tOrangeBall [ hide-turtle ]
]
set LockSynchronous_Rotation Synchronous_Rotation
set LockR R ; this is actually already set immediately after the clear-all in setup-0
set LockChoose_Simulation: Choose_Simulation:
set LockOrange_Ball_Mass: Orange_Ball_Mass:
set LockTest_Mass_Separation*: Test_Mass_Separation*:
set LockSimulation_Interval: Simulation_Interval:
set LockOrbit_Stops_At: Orbit_Stops_At:
set LockFrame_Dimension: Frame_Dimension:
set Lockx1 x1
set LockTrace_Interval: Trace_Interval:
set LockTimePerTick LockSimulation_Interval: * Time_IntervalMultiplier
ifelse LockOrbit_Stops_At: = "Never" or LockOrbit_Stops_At: = "N/A"
[ set AutoStopAngle 999999999 ]
[
let value remove " (180°)" Orbit_Stops_At:
set value remove " (270°)" value
set value remove " (360°)" value
set value remove "[ " value
set value remove " ]" value
set value remove "T" value
set value read-from-string value
set AutoStopAngle value * 360
]
ifelse LockR = 10
[ set cSourceBodyGM 4902.798E9 ] ; Moon in m^3 / s^2, source: http://ssd.jpl.nasa.gov/
[ set cSourceBodyGM 398600.440E9 ] ; Earth in m^3 / s^2, source: http://ssd.jpl.nasa.gov/
set OrbitalRadius (OrbitalPeriod ^ 2 * cSourceBodyGM / (4 * pi ^ 2)) ^ (1 / 3) ; OrbitalPeriod from preceding code
set CentroidGM 0
if LockOrange_Ball_Mass: > 0 [ set CentroidGM (6.67384E-11 * (2.51188643150958 ^ LockOrange_Ball_Mass:) * 100) ]
set cPixelsPerMeter 400 * ScreenScale / (LockFrame_Dimension: * Lockx1)
ifelse bFreeFall or not bEarthExists
[ set cOrbitalSpeed 0
set OrbitalSpeedShow "v = 0 (not an orbit)"
set OrbitalPeriodShow "N/A"
set fre uCenterText22 "N/A"
set avg-fre uCenterText22 "N/A"
]
[
set cOrbitalSpeed sqrt(cSourceBodyGM / OrbitalRadius)
set OrbitalSpeedShow (word "v = " repNumber (sqrt(cSourceBodyGM / OrbitalRadius) / 1000) 5 " km/s (calc)")
]
; starting xy coordinates and Turtles-Initialize for the orange ball + the 8 test-mass balls
; Turtles-Initialize needs: cSourceBodyGM, CentroidGM, cOrbitalSpeed, cPixelsPerMeter, {bFreeFall, bEarthExists}
;=======================================================================================================================
ask turtle tOrangeBall
[ set My-px 0
set My-py OrbitalRadius
Turtles-Initialize
set OrangeMy-px My-px
set OrangeMy-py My-py
set OrangeMy-vx My-vx
set OrangeMy-vy My-vy
set OrangeMyRadius MyRadius
set OrangeMyPhaseDeg MyPhaseDeg
; This is where we plot the orange ball. To ensure it know where it is, we reference its physical coordinates and use the same commands as Turtles-Plot
set My-fx CenterX + (My-px - OrangeMy-px) * cPixelsPerMeter
set My-fy (My-py - OrangeMy-py) * cPixelsPerMeter
setxy My-fx My-fy
]
let DoCircle false ; future use
; relative to orange ball: x-coordinate identical, the y-coordinate + Test_Mass_Separation*:
ask turtle tBlueBall_TC
[ ifelse DoCircle
[ set My-px 0
set My-py OrbitalRadius + Test_Mass_Separation*:
]
[
set My-px 0
set My-py OrbitalRadius + Test_Mass_Separation*:
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate identical, the y-coordinate - Test_Mass_Separation*:
ask turtle tVioletBall_BC
[ ifelse DoCircle
[ set My-px 0
set My-py OrbitalRadius - Test_Mass_Separation*:
]
[
set My-px 0
set My-py OrbitalRadius - Test_Mass_Separation*:
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate - Test_Mass_Separation*:, the y-coordinate identical
ask turtle tPinkBall_ML
[ ifelse DoCircle
[ set My-px 0 - Test_Mass_Separation*:
set My-py OrbitalRadius
]
[
set My-px 0 - Test_Mass_Separation*:
set My-py OrbitalRadius
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate + Test_Mass_Separation*:, the y-coordinate identical
ask turtle tWhiteBall_MR
[ ifelse DoCircle
[ set My-px 0 + Test_Mass_Separation*:
set My-py OrbitalRadius
]
[
set My-px 0 + Test_Mass_Separation*:
set My-py OrbitalRadius
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate - Test_Mass_Separation*:, the y-coordinate + Test_Mass_Separation*:
ask turtle tRedBall_TL
[ ; top left of the circle is at 135 degrees MathAngle
ifelse DoCircle
[ set My-px 0 - Test_Mass_Separation*: * cos 135
set My-py OrbitalRadius + Test_Mass_Separation*: * sin 135
]
[
set My-px 0 - Test_Mass_Separation*:
set My-py OrbitalRadius + Test_Mass_Separation*:
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate + Test_Mass_Separation*:, the y-coordinate + Test_Mass_Separation*:
ask turtle tGreenBall_TR
[ ; top right of the circle is at 45 degrees MathAngle
ifelse DoCircle
[ set My-px 0 + Test_Mass_Separation*: * cos 45
set My-py OrbitalRadius + Test_Mass_Separation*: * sin 45
]
[
set My-px 0 + Test_Mass_Separation*:
set My-py OrbitalRadius + Test_Mass_Separation*:
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate - Test_Mass_Separation*:, the y-coordinate - Test_Mass_Separation*:
ask turtle tMagentaBall_BL
[ ; bottom left of the circle is at -135 degrees MathAngle
ifelse DoCircle
[ set My-px 0 - Test_Mass_Separation*: * cos (- 135)
set My-py OrbitalRadius - Test_Mass_Separation*: * sin (- 135)
]
[
set My-px 0 - Test_Mass_Separation*:
set My-py OrbitalRadius - Test_Mass_Separation*:
]
Turtles-Initialize
]
; relative to orange ball: x-coordinate + Test_Mass_Separation*:, the y-coordinate - Test_Mass_Separation*:
ask turtle tYellowBall_BR
[ ; bottom right of the circle is at -45 degrees MathAngle
ifelse DoCircle
[ set My-px 0 + Test_Mass_Separation*: * cos (- 45)
set My-py OrbitalRadius - Test_Mass_Separation*: * sin (- 45)
]
[
set My-px 0 + Test_Mass_Separation*:
set My-py OrbitalRadius - Test_Mass_Separation*:
]
Turtles-Initialize
]
end ; setup-1-Initialize
to setup-2-Graphics
no-display
clear-drawing
ask turtle tMarker
[ ; draw a fat line down the center in case we don't use an overlay
set color gray
setxy 0 max-pycor
set heading 180
set pen-size 6
pen-down
jump 2 * max-pycor
if 1 = 2
[ ; draw centering axes on the left (dev only)
setxy min-pxcor 0
set heading 90
set color sky
set pen-size 1
pen-down
jump 400
pen-up
setxy (- CenterX) min-pycor
set heading 0
pen-down
jump 2 * max-pycor
]
]
uPark-tMarker
let ImageSuffix "_Splash.png"
if bNoSplash [ set ImageSuffix ".png" ]
if Choose_Simulation: = "Match the image"
[ if hMatch_Galaxy = 1 [ import-drawing "./GSrsc/NGC1097neg.png" ]
if hMatch_Galaxy = 2 [ import-drawing "./GSrsc/M51neg.png" ]
if hMatch_Galaxy < 1 or hMatch_Galaxy > 2
[ display ; always call display before a dialog box
user-message "Error in setup-2-Graphics; no such hMatch_Galaxy"
stop
]
]
ask turtle tReferenceFrame [ setxy (- CenterX) OrbitRadius ] ; permanent parking spot, unless R = 0
ifelse LockR = 0 ;
[ import-drawing word "./GSrsc/EmptySpace" ImageSuffix
set OrbitalPeriodShow "N/A"
ask turtle tReferenceFrame
[ set shape "frame"
setxy (- CenterX) 0
]
]
[
ifelse LockR = 1
[
set OrbitalPeriodShow "92.8588 minutes"
import-drawing word "./GSrsc/EarthISS" ImageSuffix
ask turtle tReferenceFrame [ set shape "frame-small" ]
let OutputPhrase "This photo by Paolo Nespoli shows the Shuttle Endeavor docked to the International Space Station (ISS)\n"
set OutputPhrase word OutputPhrase "< nasa.gov/mission_pages/station/main >.\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ ifelse LockR = 3
[
set OrbitalPeriodShow "95.8146 minutes"
ifelse hUser_Response = 20
[ import-drawing word "./GSrsc/Startup" ImageSuffix
set hUser_Response 0 ; 20 was the startup setting to make this happen; now we reset it.
]
[
import-drawing word "./GSrsc/EarthHST" ImageSuffix
ask turtle tReferenceFrame [ set shape "frame" ]
let OutputPhrase "This photo depicts the Hubble Telescope after the installation of new solar arrays by Shuttle mission STS-61\n"
set OutputPhrase word OutputPhrase "< nasa.gov/mission_pages/shuttle/shuttlemissions/archives/sts-61.html >.\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ ifelse LockR = 5
[ set OrbitalPeriodShow "717.9882 minutes"
import-drawing word "./GSrsc/EarthGPS" ImageSuffix
ask turtle tReferenceFrame [ set shape "frame" ]
let OutputPhrase "The artist rendering depicts the Lockheed Martin GPS III next-generation Global Positioning System satellite\n"
set OutputPhrase word OutputPhrase "< www.lockheedmartin.com/us/products/gps.html >.\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ ifelse LockR = 7
[ set OrbitalPeriodShow "23.9344696 hours"
import-drawing word "./GSrsc/EarthGeo" ImageSuffix
ask turtle tReferenceFrame [ set shape "frame" ]
let OutputPhrase "The rendering (right) employs artistic license as concerns the apparent size of the Earth; it depicts the\n"
set OutputPhrase word OutputPhrase "Artemis telecommunications satallite, which is in a geostationary orbit ~35,786 km above the Equator\n"
set OutputPhrase word OutputPhrase "< aerospace-technology.com/projects/artemis >.\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ ifelse LockR = 9
[ set OrbitalPeriodShow "27.3217 days"
ask turtle tReferenceFrame [ set shape "frame" ]
let OutputPhrase "This photo by the JAXA Kaguya spacecraft shows the Earth as seen from Lunar orbit\n"
set OutputPhrase word OutputPhrase "< kaguya.jaxa.jp/index_e.htm >.\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
ifelse bNoSplash
[ import-drawing word "./GSrsc/EarthMoon" ImageSuffix ]
[ clear-drawing
import-drawing "./GSrsc/EarthMoonX30_Splash.png"
ask turtle tMessage
[ set color black
setxy (- 220 + Screen_dx * 0.9) 12
set label "The mean Lunar orbit is about 30 Earth diameters."
show-turtle
]
drawOrbit
let TimeLeft 9
ask turtle tMarker
[ set color black
setxy (- 150 + Screen_dx / 2) 50
set label-color cyan
set label (word "Temporary Illustrative Schematic (" TimeLeft ")…")
show-turtle
]
while [ TimeLeft > 0 ]
[ wait 1
set TimeLeft TimeLeft - 1
ask turtle tMarker [ set label (word "Temporary Illustrative Schematic (" TimeLeft ")…") ]
]
no-display
uPark-tMessage
uPark-tMarker
clear-drawing
import-drawing word "./GSrsc/EarthMoon" ImageSuffix
]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ ifelse LockR = 10
[
set OrbitalPeriodShow "113.1095 minutes"
import-drawing word "./GSrsc/Moon" ImageSuffix
ask turtle tReferenceFrame [ set shape "frame-xsmall" ]
let OutputPhrase "The artist rendering (right) shows the NASA Lunar Reconnaissance Orbiter (LRO) in orbit around the Moon\n"
set OutputPhrase word OutputPhrase "< nasa.gov/mission_pages/LRO/main >. The orbital parameters shown (left) reflect the average semimajor axis\n"
set OutputPhrase word OutputPhrase "of the LRO ephemeris as measured between JDates 2455119.502 and 2455456.489 (15 Oct. 2009 – 16 Sep. 2010).\n\n"
set OutputPhrase word OutputPhrase "LRO launched from Cape Canaveral 18 June 2009; it was in Lunar orbit 5 days later < youtu.be/GCa_mHYK_Ik >.\n"
set OutputPhrase word OutputPhrase "This was just under forty years after Apollo 11 when Neil Armstrong first stepped on the Moon (20 July 1969).\n\n"
if not bSetUpButtonClicked and not bShowMe [ beep output-type OutputPhrase ]
]
;--------------------------------------------------------------------------------------------------------------------------------------------
[ let MsgPhrase "Error in setup-2-Graphics ;\n"
set MsgPhrase word MsgPhrase "no such orbital radius (R) setting for Earth."
display
user-message MsgPhrase
stop
]
]
]
]
]
]
]
drawGraphPaper
; interface display elements
;=======================================================================================================================
; main control area
ifelse LockOrange_Ball_Mass: = 0
[
Ifelse bEarthExists
[ set Orange_Ball_MassShow uCenterText22 "0.001 kg" ]
[ set Orange_Ball_MassShow uCenterText22 "0" ]
]
[ set Orange_Ball_MassShow uCenterText22 word (repNumber ((2.51188643150958 ^ LockOrange_Ball_Mass:) * 100) 0) " kg" ] ; Pogson’s formula gives a factor of 100 for 5 units on the slider with 10 being 10^7 kg.
ask turtle tOrangeMass [ set label word "m = " remove " " Orange_Ball_MassShow ]
set Test_Mass_Separation*:_Units word LockTest_Mass_Separation*: " meters (lateral/vertical)"
let unit " seconds"
if LockTimePerTick = 1 [ set unit " second" ]
set Simulation_IntervalShow uCenterText22 (word repNumber LockTimePerTick 1 unit)
; right stack
set FrameDimensionsShow uCenterText22 (word (Frame_Dimension: * Lockx1) " m × " (Frame_Dimension: * Lockx1) " m")
; <drawGraphPaper> sets GridSquareDimensionsShow
let units " ERROR"
let coefficient 1
set Trace_IntervalMultShow " × 1"
if TraceSecondsMultiplier = 6
[ ifelse LockTrace_Interval: <= 15 ; 15 is 1.5 minutes = 90 seconds
[ set units " seconds"
set coefficient TraceSecondsMultiplier
]
[
set units " minutes"
set coefficient 0.1
set Trace_IntervalMultShow " ÷ 10"
]
]
if TraceSecondsMultiplier = 60 [ set units " minutes" ]
if TraceSecondsMultiplier = 3600 [ set units " hours" ]
set Trace_IntervalShow uCenterText (word (precision (LockTrace_Interval: * coefficient) 1) units) 12
ask turtle tTraceInterval [ set label word "Δt = " (remove " " Trace_IntervalShow) ]
; bottom of left panel
; ORANGE
let Runits " km"
set OrbitalRadiusShow repNumber (OrbitalRadius / 1000) 3
if OrbitalRadius / 1000 < 10000 [ set Runits " km " ]
set OrbitalRadiusShow (word "R = " OrbitalRadiusShow Runits)
ask turtle tOrbitalRadius [ set label OrbitalRadiusShow ]
; BLUE
set cShowGM cSourceBodyGM / 1E9 / 1E6 ; GM in ×1E6 km^3 / s^2
ask turtle tGM [ set label (word "GM = " (cSourceBodyGM / 1E9 / 1E6) "E6 km^3 / s^2") ]
if not bEarthExists
[ set cShowGM CentroidGM ; GM in m^3 / s^2
ask turtle tGM
[
set label (word "GM = " repNumber CentroidGM 12 " m^3 / s^2")
set label-color orange
]
]
; top of left panel
; YELLOW
ask turtle tOrbitalSpeedCalc [ set label OrbitalSpeedShow ] ; left
ask turtle tOrbitalPeriod [ set label word "T = " OrbitalPeriodShow ] ; right
; setup-0-Clear&Reset hides these turtles, so show them now
ask turtle tReferenceFrame [ show-turtle ]
ask turtle tPartOfT [ show-turtle ]
ifelse bEarthExists
[ ask OrbitData [ show-turtle ] ]
[
ask OrbitData [ hide-turtle ]
ask turtle tPartOfT [ hide-turtle ]
ask turtle tTraceInterval [ hide-turtle ]
ask turtle tGM [ show-turtle ]
ask turtle tOrangeMass
[ show-turtle
setxy (- 218 + Screen_dx / 2) 0
]
]
end ; setup-2-Graphics
;=========================================================================================================================================================================================
; turtles
;=========================================================================================================================================================================================
; initialize coordinate and motion properties
; needs: cPixelsPerMeter, CentroidGM, cSourceBodyGM, cOrbitalSpeed, {bFreeFall, bEarthExists}
to Turtles-Initialize
set size cPixelsPerMeter
ifelse cPixelsPerMeter < 1 [ set size 1 ][ set size cPixelsPerMeter ]
if BIG [ set size cPixelsPerMeter + 1 ]
set MyRadius sqrt(My-px ^ 2 + My-py ^ 2) ; needed here to initialize the orange ball (also set in physics-5-properties)
ifelse not bEarthExists and self != turtle tOrangeBall
[ ; balls have random velocities up to separation distance escape velocity
let MaxV 0.9 * sqrt( 2 * CentroidGM / (LockTest_Mass_Separation*: * sqrt 2) )
let Vball random-float MaxV
let angle random-float 360
set My-vx Vball * cos angle
set My-vy Vball * sin angle
]
[
ifelse Choose_Simulation: = "Software test"
[ ; Each ball is in a perfect circular orbit.
let Vmag sqrt(cSourceBodyGM / MyRadius)
set My-vx Vmag * ( My-py / MyRadius )
ifelse My-px = 0
[ set My-vy 0 ] ; point to the right
[
set My-vy 0 - (Vmag * ( My-px / MyRadius ))
]
]
[
; All balls have the same initial velocity.
set My-vx cOrbitalSpeed
set My-vy 0
]
]
physics-5-properties
set EnergyStart EnergyNow ; This is the only time {EnergyStart} gets set (before the simulation starts).
physics-6-accel ; Set initial acceleration.
if MyRadius > 0 ; not true for orange ball in empty space
[ set MyPhaseInit asin(My-px / MyRadius)
set MyOmega sqrt ( cSourceBodyGM / MyRadius ^ 3 )
set MyPhaseDeg asin( My-px / MyRadius)
]
end ; Turtles-Initialize
; physics-0-sequence is at the top
to Turtles-Plot
let TimeDelta 0
if LockTrace_Interval: > 0 [ set TimeDelta remainder int(Real-time) (LockTrace_Interval: * TraceSecondsMultiplier) ]
if lateral:white/pink
[ ifelse ticks > 0 and TimeDelta = 0
[ ask (turtle-set laterals) [pen-down] ]
[ ask (turtle-set laterals) [pen-up] ]
]
if radial:blue/violet
[ ifelse ticks > 0 and TimeDelta = 0
[ ask (turtle-set radials) [pen-down] ]
[ ask (turtle-set radials) [pen-up] ]
]
if corners:red/green ; includes magenta/yellow
[ ifelse ticks > 0 and TimeDelta = 0
[ ask (turtle-set corners) [pen-down] ]
[ ask (turtle-set corners) [pen-up] ]
]
; We use My-fx, My-fy instead of built-in xcor, ycor so that turtles can live off-screen.
; When we multiply by cPixelsPerMeter, below, we imply [ cPixelsPerMeter pixels *per meter* ] or [ 1/cPixelsPerMeter meters *per pixel* ].
set My-fx CenterX + (My-px - OrangeMy-px) * cPixelsPerMeter
set My-fy (My-py - OrangeMy-py) * cPixelsPerMeter
; rotate coordinates
if LockSynchronous_Rotation
[ let rotation 0
let My-fxPreRot My-fx - CenterX ; shift back to the origin to make life easy
let My-fyPreRot My-fy
set rotation FrameIdealTheta
; rotation is compass angle, so this is the coordinate transformation
set My-fx ( (My-fxPreRot * cos rotation) - (My-fyPreRot * sin rotation) ) + CenterX ; shift back to display area
set My-fy ( (My-fxPreRot * sin rotation) + (My-fyPreRot * cos rotation) )
]
ifelse My-fx < max-pxcor and My-fx > 4 and abs My-fy < max-pycor
[ ; inside reference frame boundary
setxy My-fx My-fy
show-turtle
]
[
hide-turtle
] ; outside reference frame boundary, so hide the ball that went off screen.
if MyRelDistance > CheckMaxRange
[ set CheckMaxRange MyRelDistance
set CheckMaxRangeColor word repColorName color ": "
]
if MyRelVelocity > CheckMaxVelocity
[ set CheckMaxVelocity MyRelVelocity
set CheckMaxVelocityColor word repColorName color ": "
]
end ;Turtles-Plot
;=========================================================================================================================================================================================
; main
;=========================================================================================================================================================================================
to-report mainAny-Balls_left?
let answer false
ask radials [ if MyRelDistance > 0 [ set answer true ] ]
ask laterals [ if MyRelDistance > 0 [ set answer true ] ]
ask corners [ if MyRelDistance > 0 [ set answer true ] ]
report answer
end
to mainOutputHeader
let OutputPhrase ""
let WCol1 23
let WCol2 35
let WCol3 22
let line ""
let Col1 ""
let Col2 ""
let Col3 ""
let Col4 ""
set Col1 "SIMULATION:"
set Col2 remove " (start here)" LockChoose_Simulation:
set Col3 "Orbital_Radius:"
let detail " (ISS)"
if LockR = 3 [ set detail " (HST)" ]
if LockR = 5 [ set detail " (GPS)" ]
if LockR = 7 [ set detail " (Geostationary)" ]
if LockR = 9 [ set detail " (Moon)" ]
if LockR = 10 [ set detail " (LRO)" ]
set Col4 (word (remove "R = " OrbitalRadiusShow) detail)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 "Synchronous_Rotation:"
ifelse bFreeFall
[ set Col2 "N/A" ]
[
ifelse Synchronous_Rotation [ set Col2 "On" ][ set Col2 "Off" ]
]
set Col3 "Simulation_Interval:"
set Col4 remove " " Simulation_IntervalShow
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 "Orange_Ball_Mass:"
ifelse Orange_Ball_Mass: = 0
[ set Col2 remove " " Orange_Ball_MassShow ]
[ set Col2 (word "*** " (remove " " Orange_Ball_MassShow) " ***") ]
set Col3 "Orbit_Stops_At:"
set Col4 LockOrbit_Stops_At:
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 "Test_Mass_Separation:"
set Col2 Test_Mass_Separation*:_Units
set Col3 ""
set Col4 ""
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 ""
set Col2 ""
set Col3 "Trace_Interval:"
set Col4 remove " " Trace_IntervalShow
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 "Frame_Dimension:"
set Col2 remove " " FrameDimensionsShow
set Col3 "Draw_Graph_Paper:"
ifelse Draw_Graph_Paper [ set Col4 "On" ][ set Col4 "Off" ]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set Col1 word Col1 ""
set Col2 word Col2 ""
set Col3 word Col3 ""
set Col4 word Col4 ""
set line (word (uMakeColumn Col1 WCol1) (uMakeColumn Col2 WCol2) (uMakeColumn Col3 WCol3) Col4 "\n")
set OutputPhrase word OutputPhrase line
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
clear-output
beep
output-type OutputPhrase
output-type "=============================================================================================================\n"
end ; mainOutputHeader
to mainOutputStatus
set LastReport int(Real-time)
let vRed ""
let vBlue ""
let vGreen ""
let vPink ""
let vWhite ""
let vMagenta ""
let vViolet ""
let vYellow ""
let Absorbed " X "
let Separator " • "
let ColumnWidth 25
set PadLeftSpaces 2
ifelse is-turtle? turtle tRedBall_TL [ ask turtle tRedBall_TL [ set vRed uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vRed Absorbed ]
ifelse is-turtle? turtle tBlueBall_TC [ ask turtle tBlueBall_TC [ set vBlue uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vBlue Absorbed ]
ifelse is-turtle? turtle tGreenBall_TR [ ask turtle tGreenBall_TR [ set vGreen uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vGreen Absorbed ]
ifelse is-turtle? turtle tPinkBall_ML [ ask turtle tPinkBall_ML [ set vPink uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vPink Absorbed ]
ifelse is-turtle? turtle tWhiteBall_MR [ ask turtle tWhiteBall_MR [ set vWhite uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vWhite Absorbed ]
ifelse is-turtle? turtle tMagentaBall_BL [ ask turtle tMagentaBall_BL [ set vMagenta uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vMagenta Absorbed ]
ifelse is-turtle? turtle tVioletBall_BC [ ask turtle tVioletBall_BC [ set vViolet uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vViolet Absorbed ]
ifelse is-turtle? turtle tYellowBall_BR [ ask turtle tYellowBall_BR [ set vYellow uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator repNumber MyRelDistance 3 ) ColumnWidth ] ][ set vYellow Absorbed ]
set PadLeftSpaces 0
let OutputPhrase word "Realtime (hh:mm:ss): " (remove " " Real-timeShow)
let Ender ""
ifelse bFreeFall
[ ask turtle tOrangeBall
[ set OutputPhrase (word OutputPhrase "; Geocentric range (R): " (repNumber ((My-py / 1000)) 3) " km; Radial velocity: " (repNumber My-vy 3) " m/s.\n")
set OutputPhrase (word OutputPhrase "Velocity correction calculated from energy conservation: " repNumber ffv-correction 7 " m/s.\n")
; update the left panel display value
let NewRadius My-py
let Runits " km"
let NewRadiusShow repNumber (NewRadius / 1000) 3
if NewRadius / 1000 < 10000 [ set Runits " km " ]
set NewRadiusShow (word "R = " NewRadiusShow Runits)
ask turtle tOrbitalRadius [ set label NewRadiusShow ]
]
]
[
if bEarthExists [ set OutputPhrase (word OutputPhrase " (" (repNumber ( Real-time / OrbitalPeriod) 3) "T)") ]
set OutputPhrase (word OutputPhrase "; Max. values: " (remove " " MaxVelocityShow) " cm/s; " (remove " " MaxRangeShow) " m.\n")
set Ender "\n"
]
set OutputPhrase (word OutputPhrase "Velocity (cm/s) and • Distance (m) relative to the orange ball at the centroid:\n\n")
set OutputPhrase (word OutputPhrase "red: " vRed)
set OutputPhrase (word OutputPhrase "blue: " vBlue)
set OutputPhrase (word OutputPhrase "green: " vGreen "\n")
set OutputPhrase (word OutputPhrase "pink: " vPink)
let OrangeBallText (uMakeColumn (word "orange ball (m = " (remove " " Orange_Ball_MassShow) ")") (ColumnWidth + 8) )
set OutputPhrase word OutputPhrase OrangeBallText
set OutputPhrase (word OutputPhrase "white: " vWhite "\n")
set OutputPhrase (word OutputPhrase "magenta: " vMagenta)
set OutputPhrase (word OutputPhrase "violet: " vViolet)
set OutputPhrase (word OutputPhrase "yellow: " vYellow "\n\n")
set OutputPhrase (word OutputPhrase Ender)
; no beep
output-type OutputPhrase ; This method gives a better presentation than a series of output-print commands.
end ; mainOutputStatus
to mainOutputStatus2
set LastReport int(Real-time)
let vRed ""
let vBlue ""
let vGreen ""
let vPink ""
let vWhite ""
let vMagenta ""
let vViolet ""
let vYellow ""
let Absorbed " X "
let Separator " ◊ "
let ColumnWidth 26
set PadLeftSpaces 2
ifelse is-turtle? turtle tRedBall_TL [ ask turtle tRedBall_TL [ set vRed uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vRed Absorbed ]
ifelse is-turtle? turtle tBlueBall_TC [ ask turtle tBlueBall_TC [ set vBlue uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vBlue Absorbed ]
ifelse is-turtle? turtle tGreenBall_TR [ ask turtle tGreenBall_TR [ set vGreen uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vGreen Absorbed ]
ifelse is-turtle? turtle tPinkBall_ML [ ask turtle tPinkBall_ML [ set vPink uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vPink Absorbed ]
ifelse is-turtle? turtle tWhiteBall_MR [ ask turtle tWhiteBall_MR [ set vWhite uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vWhite Absorbed ]
ifelse is-turtle? turtle tMagentaBall_BL [ ask turtle tMagentaBall_BL [ set vMagenta uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vMagenta Absorbed ]
ifelse is-turtle? turtle tVioletBall_BC [ ask turtle tVioletBall_BC [ set vViolet uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vViolet Absorbed ]
ifelse is-turtle? turtle tYellowBall_BR [ ask turtle tYellowBall_BR [ set vYellow uMakeColumn (word uPadRight (repNumber (MyRelVelocity * 100) 5) 8 Separator (repScientific EnergyNow 4) ) ColumnWidth ] ][ set vYellow Absorbed ]
set PadLeftSpaces 0
let OutputPhrase word "Realtime (hh:mm:ss): " (remove " " Real-timeShow)
ask turtle tOrangeBall
[ set OutputPhrase (word OutputPhrase "; Geocentric range (R): " (repNumber ((My-py / 1000)) 3) " km; Radial velocity: " (repNumber My-vy 3) " m/s.\n") ] ; should be 0
set OutputPhrase (word OutputPhrase "Velocity (cm/s) and ◊ Total Energy (J) relative to the orange ball at the centroid:\n")
set OutputPhrase (word OutputPhrase "Inconstant Total Energy implies simulation error; reduce Δt and/or centroid mass.\n\n")
set OutputPhrase (word OutputPhrase "red: " vRed)
set OutputPhrase (word OutputPhrase "blue: " vBlue)
set OutputPhrase (word OutputPhrase "green: " vGreen "\n")
set OutputPhrase (word OutputPhrase "pink: " vPink)
let OrangeBallText (uMakeColumn (word "orange ball (m = " (remove " " Orange_Ball_MassShow) ")") (ColumnWidth + 8) )
set OutputPhrase word OutputPhrase OrangeBallText
set OutputPhrase (word OutputPhrase "white: " vWhite "\n")
set OutputPhrase (word OutputPhrase "magenta: " vMagenta)
set OutputPhrase (word OutputPhrase "violet: " vViolet)
set OutputPhrase (word OutputPhrase "yellow: " vYellow "\n\n")
; no beep
output-type OutputPhrase ; This method gives a better presentation than a series of output-print commands.
end ; mainOutputStatus2
to mainShowMax
; Report MaxRange and MaxVelocity, which Check values are set in <Turtles-Plot>.
if CheckMaxRange > MaxRange
[ set MaxRange CheckMaxRange
set MaxRangeColor CheckMaxRangeColor
]
if CheckMaxVelocity > MaxVelocity
[
set MaxVelocity CheckMaxVelocity
set MaxVelocityColor CheckMaxVelocityColor
]
set MaxRangeShow uCenterText22 (word CheckMaxRangeColor (repNumber MaxRange 3))
set MaxVelocityShow uCenterText22 (word CheckMaxVelocityColor (repNumber (MaxVelocity * 100) 5))
end
;=========================================================================================================================================================================================
; draw
;=========================================================================================================================================================================================
to drawGraphPaper
ifelse not Draw_Graph_Paper
[ set GridSquareDimensionsShow "↕Draw_Graph_Paper -Off-" ]
[
no-display ; be sure to run display at some point afterwards
let StandardColor 2
let HighlightColor 3
let AxisColor gray
let GridDimension 400 * ScreenScale
let GridZero-x CenterX
let GridZero-y 0
let DotSpace 2000 * ScreenScale / (LockFrame_Dimension:) ; (400 pix / Frame_Dimension) * 5 m / square
let LinesToSide int (max-pycor / DotSpace)
if LinesToSide > 15
[ set DotSpace 4000 * ScreenScale / (LockFrame_Dimension:) ; (400 pix / Frame_Dimension) * 10 m / square
set LinesToSide int (max-pycor / DotSpace)
]
let TotalLines 1 + 2 * LinesToSide ; center line plus 2 * lines per 1/2 of screen
let GridSquareDimension int (LockFrame_Dimension: * x1 / 2 / LinesToSide)
set GridSquareDimensionsShow uCenterText22 (word GridSquareDimension " m × " GridSquareDimension " m")
let FirstHighlight LinesToSide mod int(LinesToSide / 5)
let DotColor StandardColor
ask turtle tMarker
[ set pen-size 1
set color StandardColor
pen-up
let LinesDrawn 0
set heading 0
repeat TotalLines
[ ; draw vertical lines from left to right
setxy (GridZero-x - (DotSpace * LinesToSide) + (LinesDrawn * DotSpace)) min-pycor
pen-down
ifelse (LinesDrawn - FirstHighlight) mod 5 = 0 ; Highlight every 5th line from midline.
[ set color HighlightColor ]
[ set color StandardColor ]
if xcor = GridZero-x [ set color AxisColor ]
jump (2 * max-pycor)
pen-up
set LinesDrawn (LinesDrawn + 1)
]
set LinesDrawn 0
set heading 90
repeat TotalLines
[ ; draw horizontal lines from bottom to top
setxy (GridZero-x - GridDimension / 2) (GridZero-y - (DotSpace * LinesToSide) + (LinesDrawn * DotSpace))
pen-down
ifelse (LinesDrawn - FirstHighlight) mod 5 = 0 ; Highlight every 5th line from midline.
[ set color HighlightColor ]
[ set color StandardColor ]
if ycor = GridZero-y [ set color AxisColor ]
jump (GridDimension)
pen-up
set LinesDrawn (LinesDrawn + 1)
]
set color AxisColor
;redraw x-axis
set heading 90
setxy 4 0
pen-down
jump (GridDimension)
pen-up
;redraw y-axis
set heading 0
setxy CenterX min-pycor
pen-down
jump (GridDimension)
pen-up
]
uPark-tMarker
]
end ; drawGraphPaper
to drawOrbit ; This routine is not tick-based.
set LockSynchronous_Rotation Synchronous_Rotation
ask turtle tReferenceFrame
[
let TraceAngleDelta precision (Trace_Interval: * TraceSecondsMultiplier / OrbitalPeriod * 360) 1 ; Trace_Interval: is set in minutes
let NextTracePhase 0 ; start tracing immediately
let PhaseAngle 0 ; starting location in NetLogo world (12 o'clock position)
let interval 0.002
if not bShowMe
[
set interval 0
no-display
]
let PenIsDown false
while [ PhaseAngle <= 360 ]
[ if Synchronous_Rotation != LockSynchronous_Rotation and interval != 0
[ display ; always call display before a dialog box
user-message "You cannot change ↕Synchronous_Rotation during an orbit."
set Synchronous_Rotation LockSynchronous_Rotation
]
every interval
[
if not mouse-down?
[
if LockSynchronous_Rotation
[ set heading PhaseAngle
if bShowMe [ ask turtle tGyroOrange [ set heading (- PhaseAngle) ]
; These are hidden until the second phase of the demo; it doesn't matter if they rotate.
if LockSynchronous_Rotation
[ ask turtle tGyroRed [ set heading (- PhaseAngle) ]
ask turtle tGyroGreen [ set heading (- PhaseAngle) ] ; always exists with tGyroRed
]
]
]
ifelse TraceAngleDelta = 0 [ pen-down ]
[ ifelse PhaseAngle >= NextTracePhase and PhaseAngle < (NextTracePhase + 0.2)
[ pen-down
set PenIsDown true
]
[
pen-up
if PenIsDown
[ set PenIsDown false
set NextTracePhase NextTracePhase + TraceAngleDelta
]
]
]
setxy ((- CenterX) + (OrbitRadius * cos repMathAngle PhaseAngle)) (OrbitRadius * sin repMathAngle PhaseAngle)
if bShowMe
[ if not LockSynchronous_Rotation
[ ask turtle tGyroRed [ setxy (CenterX + (GyroOffset * cos repMathAngle (PhaseAngle - 90) )) (GyroOffset * sin repMathAngle (PhaseAngle - 90)) ] ; starts on the LHS of orange ball
ask turtle tGyroGreen [ setxy (CenterX + (GyroOffset * cos repMathAngle (PhaseAngle + 90))) (GyroOffset * sin repMathAngle (PhaseAngle + 90)) ] ; starts on the RHS of orange ball
]
; These are hidden until the third phase of the demo; it doesn't matter if they rotate.
ask turtle tLittleGyroRed [ setxy ((- CenterX) + (OrbitRadius * cos repMathAngle (MyPhaseInit + PhaseAngle))) (OrbitRadius * sin repMathAngle (MyPhaseInit + PhaseAngle)) ] ; identical motion to tReferenceFrame, but the PhaseAngle is different
ask turtle tLittleGyroGreen [ setxy ((- CenterX) + (OrbitRadius * cos repMathAngle (MyPhaseInit + PhaseAngle))) (OrbitRadius * sin repMathAngle (MyPhaseInit + PhaseAngle)) ] ; identical motion to tReferenceFrame, but the PhaseAngle is different
]
let value word (precision (PhaseAngle / 360) 2) "" ; 0.50
if length value = 3 [ set value word value "0" ]
ask turtle tPartOfT [ set label (word "t = " value "T") ]
set PhaseAngle PhaseAngle + 0.1
] ; every interval (end)
] ; not mouse-down? (end)
]
pen-up
setxy (- CenterX) OrbitRadius ; parked position
ask turtle tPartOfT [ set label "t = 0.000T" ]
display
]
end ; drawOrbit
;=========================================================================================================================================================================================
; utilities
;=========================================================================================================================================================================================
to-report uCenterText [ ToBeCentered MonitorWidth ]
set ToBeCentered word ToBeCentered ""
let TextLength length ToBeCentered
let SpacesNeeded int(((MonitorWidth / 2) - (TextLength / 2)) * 2)
if SpacesNeeded mod 2 != 0 [ set SpacesNeeded SpacesNeeded + 1 ] ; Always have even number of spaces so that [ remove " " text works ].
repeat SpacesNeeded [ set ToBeCentered word " " ToBeCentered ]
report ToBeCentered
end
to-report uCenterText22 [ ToBeCentered ]
set ToBeCentered word ToBeCentered ""
let TextLength length ToBeCentered
let SpacesNeeded int((11 - (TextLength / 2)) * 2.3)
if SpacesNeeded mod 2 != 0 [ set SpacesNeeded SpacesNeeded + 1 ] ; Always have even number of spaces so that [ remove " " text works ].
repeat SpacesNeeded [ set ToBeCentered word " " ToBeCentered ]
report ToBeCentered
end
to-report uMakeColumn [ ColumnText ColumnWidth ]
let TextLength length ColumnText
let SpacesNeeded ColumnWidth - TextLength
repeat SpacesNeeded [ set ColumnText word ColumnText " " ]
report ColumnText
end
to-report uPadRight [ ToBePadded TextLength ]
set ToBePadded word ToBePadded ""
let SpacesNeeded TextLength - length ToBePadded
repeat SpacesNeeded
[ set ToBePadded word ToBePadded " " ]
report ToBePadded
end
to-report uPadTrailingZeros [ NumberString decimals ]
if decimals > 0 and not is-number? position "E" NumberString ; Don't pad scientific notation.
[ let ZeroPadding decimals
if not is-number? position "." NumberString [ set NumberString word NumberString "." ]
let WhereIsDecimal position "." NumberString
set ZeroPadding decimals - (length NumberString - WhereIsDecimal - 1)
if ZeroPadding = 1 [ set NumberString word NumberString "0" ]
if ZeroPadding = 2 [ set NumberString word NumberString "00" ]
if ZeroPadding = 3 [ set NumberString word NumberString "000" ]
if ZeroPadding = 4 [ set NumberString word NumberString "0000" ]
if ZeroPadding = 5 [ set NumberString word NumberString "00000" ]
if ZeroPadding = 6 [ set NumberString word NumberString "000000" ]
]
report NumberString
end
to uPark-tMarker
ask turtle tMarker
[ ; parking conditions
hide-turtle
pen-up
setxy 0 0
set color black
set label ""
set label-color white
]
end
to uPark-tMessage
ask turtle tMessage
[ ; parking conditions
hide-turtle
pen-up
setxy 0 0
set color black
set label ""
set label-color white
]
ask turtle tMessage2
[ ; parking conditions
hide-turtle
pen-up
setxy 0 0
set color black
set label ""
set label-color white
]
end
;=========================================================================================================================================================================================
to-report repMathAngle [h]
report (90 - h) mod 360 ; convert NetLogo compass heading (angle) to a standard mathematical angle on the unit circle
end
; report the name of a color
to-report repColorName [cnum]
let MyColor "?"
ifelse (cnum mod 10 = 0) [ set MyColor "black" ]
[ ifelse ((cnum + 0.1) mod 10 = 0) [ set MyColor "white" ]
[ ifelse (cnum < 10) [ set MyColor "gray" ]
[ ifelse (cnum < 20) [ set MyColor "red" ]
[ ifelse (cnum < 30) [ set MyColor "orange" ]
[ ifelse (cnum < 40) [ set MyColor "brown" ]
[ ifelse (cnum < 50) [ set MyColor "yellow" ]
[ ifelse (cnum < 60) [ set MyColor "green" ]
[ ifelse (cnum < 70) [ set MyColor "lime" ]
[ ifelse (cnum < 80) [ set MyColor "turquoise" ]
[ ifelse (cnum < 90) [ set MyColor "cyan" ]
[ ifelse (cnum < 100) [ set MyColor "sky" ]
[ ifelse (cnum < 110) [ set MyColor "blue" ]
[ ifelse (cnum < 120) [ set MyColor "violet" ]
[ ifelse (cnum < 130) [ set MyColor "magenta" ]
[ if (cnum < 140) [ set MyColor "pink" ]
]]]]]]]]]]]]]]]
if (MyColor != "black") and (MyColor != "white")
[ if cnum mod 5 != 0
[ ifelse (cnum + 2) mod 5 = 0 and cnum mod 2 = 1 [ set MyColor word "night " MyColor ]
[ ifelse (cnum + 1) mod 5 = 0 and cnum mod 2 = 0 [ set MyColor word "dark " MyColor ]
[ ifelse (cnum - 1) mod 5 = 0 and cnum mod 2 = 0 [ set MyColor word "light " MyColor ]
[ ifelse (cnum - 2) mod 5 = 0 and cnum mod 2 = 1 [ set MyColor word "pastel " MyColor ]
[ set MyColor word "other " MyColor ]
]]]]]
if not bPreciseColors
[ if MyColor = "lime" [ set MyColor "green" ]
if MyColor = "sky" [ set MyColor "blue" ]
]
report MyColor
end ; repColorName
; time in seconds returned as "y d (hh:mm:ss)"
to-report repHumanTime [TimeInSeconds]
let years int (TimeInSeconds / 31557600) ; Julian year
ifelse years = 0 [ set years "" ][ set years word years " y " ]
let days int ((TimeInSeconds mod 31557600) / (24 * 3600))
ifelse days = 0 [ set days "" ][ set days word days " d " ]
let hours int ((TimeInSeconds mod (24 * 3600)) / 3600)
if hours < 10 [ set hours word "0" hours ]
let minutes int ((TimeInSeconds mod 3600) / 60)
if minutes < 10 [ set minutes word "0" minutes ]
let seconds int (TimeInSeconds mod 60)
if seconds < 10 [ set seconds word "0" seconds ]
let HumanTime (word years days hours ":" minutes ":" seconds)
report HumanTime
end
; any number returned as string x.nnnEm where nnn is 3 decimals and m is magnitude
to-report repScientific [MyNumber decimals ]
let magnitude 0
let sign " "
if MyNumber < 0 [ set sign "-" ]
set MyNumber abs MyNumber
ifelse MyNumber < 1 and MyNumber != 0
[ while [ MyNumber < 1 ]
[ set MyNumber MyNumber * 10
set magnitude magnitude + 1
]
set MyNumber word (precision MyNumber decimals) ""
ifelse magnitude >= 10 [ set MyNumber (word (uPadTrailingZeros MyNumber decimals) "E-" magnitude) ][ set MyNumber (word (uPadTrailingZeros MyNumber decimals) "E-0" magnitude) ]
]
[ ; number is >= 1
set magnitude -1
while [ MyNumber >= 1 ]
[ set MyNumber MyNumber / 10
set magnitude magnitude + 1
]
if MyNumber = 0 [ set magnitude 0 ]
set MyNumber word (precision (MyNumber * 10) decimals) ""
ifelse magnitude >= 10 [ set MyNumber (word (uPadTrailingZeros MyNumber decimals) "E+" magnitude) ][ set MyNumber (word (uPadTrailingZeros MyNumber decimals) "E+0" magnitude) ]
]
report word sign MyNumber
end
; Large numbers are returned as string with comma, if < 1E6, or scientific notation, if >= 1E6.
; This works just like the NetLogo "precision" command, except it yields a string and pads trailing zeros.
to-report repNumber [MyNumber decimals]
let ShowNumber "0"
let sign ""
let LeftOfDecimal length (word (int MyNumber) "")
ifelse abs MyNumber < 1000
[ set ShowNumber word (precision MyNumber decimals) ""
set ShowNumber uPadTrailingZeros ShowNumber decimals
]
[
if MyNumber < 0 [ set sign "-" ]
set MyNumber abs MyNumber
let HowBig int (MyNumber / 1E6)
ifelse HowBig > 0
[ set HowBig word HowBig ""
let magnitude length HowBig + 5
set ShowNumber precision (MyNumber / (10 ^ magnitude)) decimals
set ShowNumber word ShowNumber ""
if length ShowNumber >= (2 + decimals) [ set ShowNumber substring ShowNumber 0 (2 + decimals) ]
set ShowNumber uPadTrailingZeros ShowNumber decimals
set ShowNumber (word ShowNumber "E" magnitude)
set LeftOfDecimal 1
]
[
let thousands int (MyNumber / 1000)
let rest precision (MyNumber - (1000 * thousands)) decimals
ifelse rest < 10 [ set rest word "00" rest ][ if rest < 100 [ set rest word "0" rest ] ]
set ShowNumber (word thousands "," rest)
set ShowNumber uPadTrailingZeros ShowNumber decimals
]
]
let PadSpaces PadLeftSpaces - LeftOfDecimal
if PadSpaces > 0
[ repeat PadSpaces
[ set sign word " " sign ]
]
report word sign ShowNumber
end ; repNumber
; END OF CODE
; Code and interface are Copyright © 2012–2013 Alexander F. Mayer < GravitySim.net > & < SensibleUniverse.com >