Skip to content

Commit

Permalink
flip fitness algorithm when targetRatio is >1, #345
Browse files Browse the repository at this point in the history
  • Loading branch information
zepumph committed Feb 13, 2021
1 parent a5037cd commit 6d5fb74
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
14 changes: 8 additions & 6 deletions doc/implementation-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ An algorithm is used to determine how accurate the current ratio is to the targe
see `ratioFitnessProperty`. This algorithm went through a lot of prototyping (see
https://github.com/phetsims/ratio-and-proportion/issues/14). The algorithm that is used predominately takes into
consideration the visual/spacial distance that the consequent hand can travel from the "in proportion" state (see below)
, before being "far from proportion". When the tick marks are showing 0-10, the consequent can move two tick marks away
from the "in proportion" value before the `ratioFitnessProperty` is 0. Because of the relationship ratio terms have, the
antecedent value's distance between being in-proportion and far-from proportion varies based on the target ratio. The
fitness algorithm is based on the euclidean distance between two points, the current ratio and the target ratio. These
points are calculated by using the current ratio to get a function with an inverse slope to the function of the target
ratio. See `RAPModel.calculateFitness()` for details.
, before being "far from proportion". When the tick marks are showing 0-10 with a targetRatio of >1, the consequent can
move two tick marks away from the "in proportion" value before the `ratioFitnessProperty` is 0. Because of the
relationship ratio terms have, the antecedent value's distance between being in-proportion and far-from proportion
varies based on the target ratio. The fitness algorithm is based on the euclidean distance between two points, the
current ratio and the target ratio. These points are calculated by using the current ratio to get a function with an
inverse slope to the function of the target ratio. When the targetRatio is `>1`, the fitness algorithm is reversed such
that the antecedent and consequent are flipped. This is to give consistent fitness relationship for `targetRatio=1/10` and
`targetRatio=10`. See `RAPModel.calculateFitness()` for details.

## Model states

Expand Down
17 changes: 16 additions & 1 deletion js/common/model/RAPModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,12 @@ unclampedFitness: ${unclampedFitness}
/**
* This fitness algorithm is explained in https://github.com/phetsims/ratio-and-proportion/issues/325. It is based
* on plotting the perpendicular intersection between a point representing the current ratio, and the function of the
* target ratio. This is possible because the ratio term values are normalized between 0 and 1
* target ratio. This is possible because the ratio term values are normalized between 0 and 1.
*
* NOTE: when targetRatio is greater than 1, the algorithm is flipped to yield the same fitness relationship to the
* larger term value. Thus moving the consequent when the target ratio is 1/2 will yield identical fitness to moving the
* antecedent when the target ratio is 2.
*
* (see RAPConstants.TOTAL_RATIO_TERM_VALUE_RANGE).
* @param {number} antecedent
* @param {number} consequent
Expand All @@ -116,6 +121,16 @@ unclampedFitness: ${unclampedFitness}
*/
calculateFitness( antecedent, consequent, targetRatio ) {

// This fitness algorithm was designed and executed to target ratios between 0 and 1, when larger, the fitness looks
// best if the reciprocal is calculated (yielding a similar relationship between the consequent and target ratio of X,
// as with antecedent when the targetRatio is 1/X). See https://github.com/phetsims/ratio-and-proportion/issues/345
if ( targetRatio > 1 ) {
const oldAnt = antecedent;
antecedent = consequent;
consequent = oldAnt;
targetRatio = 1 / targetRatio;
}

// Calculate the inverse slope from the current target ratio.
const coefficient = -1 / targetRatio;

Expand Down

0 comments on commit 6d5fb74

Please sign in to comment.