Skip to content

Latest commit

 

History

History
74 lines (54 loc) · 4.81 KB

implementation-notes.md

File metadata and controls

74 lines (54 loc) · 4.81 KB

Hooke's Law - Implementation Notes

This document contains notes that will be helpful to developers and future maintainers of this simulation.

Model

Start by reading the model description in https://github.com/phetsims/hookes-law/blob/main/doc/model.md

Type Spring is the heart of the model, start there. Type SeriesSystem and ParallelSystem expand the model to describe series and parallel configurations of 2 springs.

The model is 1 dimensional. Everything occurs along the x (horizontal) axis, with positive values to the right.

Since the model is 1-dimensional, various "vectors" (e.g. appliedForceVector) are implemented as scalars. This simplifies the implementation, and allows us to use simple numbers rather than allocating Vector objects.

For systems of springs, the classical model equations use subscripts '1' and '2' to refer to the springs in a system ( e.g. k1, k2). Rather than use subscripts, this implementations uses "left" and "right" (for 2 springs in series), "top" and "bottom" (for 2 springs in parallel).

For systems containing more than one spring, you'll see the term "equivalent spring". This is the single spring that is equivalent to the system.

The model is general and supports some things that springs shouldn't do when in a system. For example, the general model supports moving the left end of a spring. But in a series system, the left end of the left spring should remain connected to the wall at all times. Throughout the implementation, assertions are used to guard against these types of violations.

View

Because the model is 1 dimensional, the 2D model-view transform (ModelViewTransform2) that is typically found in PhET simulations is not required. All conversions between model and view coordinate frames are done using unit vectors lengths for the various 1-dimensional quantities (displacement, force, energy). See HookesLawConstants.UNIT_*.

The robotic arm has a pair of pincers that are open when displacement is zero and no user interaction is taking place. In order to determine whether user interaction is taking place, Property numberOfInteractionsInProgressProperty is passed to all user-interface components that affect displacement. This includes the robotic arm itself, and all NumberControls. When an interaction begins, numberOfInteractionsInProgressProperty is incremented; when an interaction ends, numberOfInteractionsInProgressProperty is decremented. The pincers are opened only when ( displacement === 0 && numberOfInteractionsInProgressProperty.get() === 0 ).

The implementation of the spring view is based on a parametric equation known as the prolate cycloid. See the documentation in ParametricSpringNode for details.

Reentrant Properties

A few Properties require the use of the reentrant: true option, because they participate in cyclic relationships, and because their computation is prone to floating-point error that triggers cycles.

The first relationship is x = p - e, where x is the spring's displacement from equilibrium, p is the position of the robotic arm's pincer, and e is the spring's equilibrium position. The user can change x ( via a slider) or p (by dragging the robotic arm). Changing x results in computation of p; changing p results in computation of p. So the Properties for x and p, displacementProperty in Spring and leftProperty in RoboticArm respectively, have reentrant: true.

The second relationship is F = kx, where F is applied force, k is spring constant, and x is the spring's displacement from equilibrium. The user can change F, k and x. Changing x results in computation of F; changing F results in computation of x. (k can be ignored for the purposes of this discussion.) So the Properties for x and F, displacementProperty and appliedForceProperty respectively in Spring, require reentrant: true.

Miscellaneous

Regarding memory management: Everything created in this sim (model and view) exists for the lifetime of the sim, there is no dynamic creation/deletion of objects. All observer/observable relationships also exist for the lifetime of the sim. So there is no need to call the various memory-management functions associated with objects (unlink, dispose, detach, etc.)

For a list of query parameters that are specific to this simulation, see HookesLawQueryParameters.