phetsims / calculus-grapher

"Calculus Grapher" is an educational simulation in HTML5, by PhET Interactive Simulations.
GNU General Public License v3.0
4 stars 4 forks source link

Triangle and Parabola Mode Interactions with Discontinuities #295

Closed veillette closed 1 year ago

veillette commented 1 year ago

Calculus Grapher screenshot (49)

Adding a triangle near a discontinuities (highlighted below) deletes the state of the discontinuities .

InkedCalculus Grapher screenshot (50)

veillette commented 1 year ago

This is done is the commit below.

The iterateFunctionOverPoints method already identified properly the transition points of the new function and the old curve. However, it wrongly assumed that the function and the old curve would meet at a point and create a cusp. Instead, we need to check if the gap between the two edge points is large and if so, assign them the 'discontinuous' type. If not they are 'cusp'

if ( wasPreviousPointModified !== null && wasPreviousPointModified !== isModified ) {

        const rightPoint = point;
        const leftPoint = this.points[ index - 1 ];

        // If the gap between the two points is large, label them as 'discontinuous', otherwise label them as 'cusp'.
        const yDifference = Math.abs( rightPoint.y - leftPoint.y );
        const isGapLarge = yDifference > THRESHOLD_GAP;
        rightPoint.pointType = isGapLarge ? 'discontinuous' : 'cusp';
        leftPoint.pointType = rightPoint.pointType;
      }
veillette commented 1 year ago

In the commit below I removed the arbitrariness of the threshold gap, which is merely another magic number. Instead, I think it is best to rely on the previously saved pointType.

The discontinuity stays a discontinuity until it closes, which is probably what a mathematician is the appropriate behavior.

 // Context: The updated y values will result in a piecewise function of the new function and the old y-values.
      // We need to identify the points where the transitions happen. Those points will be labeled cusps or discontinuities
      if ( wasPreviousPointModified !== null && wasPreviousPointModified !== isModified ) {

        // We always label discontinuities and cusps on an adjacent pair of points.
        const rightPoint = point;
        const leftPoint = this.points[ index - 1 ];

        // If the right point (point inside the new function) used to be discontinuous, leave type as is, Otherwise label it as cusp.
        rightPoint.pointType = rightPoint.lastSavedType === 'discontinuous' ? 'discontinuous' : 'cusp';

        // The left point should have the same pointType as its adjacent pair point
        leftPoint.pointType = rightPoint.pointType;

      }

The transition regions can now create discontinuities as seen in the screenshot below.

image

veillette commented 1 year ago

This is working well. I think this approach based our the previous point type. I'll go ahead and close this issue, as it is very simple code-wise. QA can raise a new issue if they find problems with the discontinuities.