Skip to content

Commit

Permalink
Use color palette for orbital areas, see #38
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinVallejo committed Jun 1, 2023
1 parent 3c8bf09 commit 25b2ea2
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 25 deletions.
9 changes: 8 additions & 1 deletion js/common/model/EllipticalOrbitEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export default class EllipticalOrbitEngine extends Engine {

public totalArea = 1;
public segmentArea = 1;
public activeAreaIndex = 0;

public tracingPathProperty = new BooleanProperty( false );
public periodTraceStart = 0;
Expand Down Expand Up @@ -340,7 +341,10 @@ export default class EllipticalOrbitEngine extends Engine {
let previousNu = 0;
let bodyAngle = -this.nu;

// The area of one section of the ellipse
this.segmentArea = this.totalArea / this.periodDivisions;

// The angle of one section of the ellipse
const angularSection = TWOPI / this.periodDivisions;

this.orbitalAreas.forEach( ( orbitalArea, i ) => {
Expand All @@ -363,6 +367,7 @@ export default class EllipticalOrbitEngine extends Engine {
if ( startAngle <= bodyAngle && bodyAngle < endAngle ) {
orbitalArea.insideProperty.value = true;
orbitalArea.alreadyEntered = true;
this.activeAreaIndex = orbitalArea.index;

// Map opacity from 0 to 1 based on BodyAngle from startAngle to endAngle (inside area)
if ( this.retrograde ) {
Expand Down Expand Up @@ -403,8 +408,10 @@ export default class EllipticalOrbitEngine extends Engine {
} );
}

/**
* Angular difference as calculated by the mean anomaly, i.e. independent of the eccentricity.
*/
private meanAnomalyDiff( startAngle: number, endAngle: number ): number {
// Convert angles from foci to center to get the correct area
return Utils.moduloBetweenDown( this.getMeanAnomaly( endAngle, this.e ) - this.getMeanAnomaly( startAngle, this.e ), 0, TWOPI );
}

Expand Down
47 changes: 47 additions & 0 deletions js/common/model/KeplersLawsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import ReadOnlyProperty from '../../../../axon/js/ReadOnlyProperty.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import keplersLaws from '../../keplersLaws.js';
import PeriodTracker from './PeriodTracker.js';
import OrbitalArea from './OrbitalArea.js';
import { Color } from '../../../../scenery/js/imports.js';
import Utils from '../../../../dot/js/Utils.js';

type SuperTypeOptions = CommonModelOptions<EllipticalOrbitEngine>;

Expand Down Expand Up @@ -195,6 +198,50 @@ class KeplersLawsModel extends SolarSystemCommonModel<EllipticalOrbitEngine> {
super.step( dt );
this.periodPath.step( dt );
}

/**
* Retrieves the color of the given orbital area, based on which is active and the palette.
* @param area
*/
public getAreaColor( area: OrbitalArea ): Color {
const colorPalette = [
'#FF92FF',
'#FF6DFF',
'#FF24FF',
'#C800C8',
'#A400A4',
'#80007F'
];

// Easter egg color palette
// const colorPalette = [
// '#FFB3BA', // Pastel Red
// '#FFDFB9', // Pastel Orange
// '#FFFFB3', // Pastel Yellow
// '#B5FFB3', // Pastel Green
// '#B3FFFF', // Pastel Blue
// '#D1B3FF' // Pastel Purple
// ];
const numAreas = this.periodDivisionProperty.value;
const activeAreaIndex = this.engine.activeAreaIndex;

let colorIndex;

// Calculate the index difference and map it to color palette.
let indexDiff = this.engine.retrograde ? area.index - activeAreaIndex : activeAreaIndex - area.index;
indexDiff = Utils.moduloBetweenDown( indexDiff, 0, numAreas );

colorIndex = indexDiff;
if ( numAreas < colorPalette.length ) {
colorIndex = Math.floor( indexDiff * colorPalette.length / numAreas );
}
if ( indexDiff === numAreas - 1 ) {
colorIndex = colorPalette.length - 1;
}

return new Color( colorPalette[ colorIndex ] ).setAlpha( area.alreadyEntered ? 1 : 0 );

}
}

keplersLaws.register( 'KeplersLawsModel', KeplersLawsModel );
Expand Down
21 changes: 0 additions & 21 deletions js/common/model/OrbitalArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
import Vector2 from '../../../../dot/js/Vector2.js';
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import keplersLaws from '../../keplersLaws.js';
import KeplersLawsConstants from '../../KeplersLawsConstants.js';
import Utils from '../../../../dot/js/Utils.js';
import { Color } from '../../../../scenery/js/imports.js';

export default class OrbitalArea {
public dotPosition = Vector2.ZERO; // Position of the dot in the orbital area
Expand All @@ -29,24 +26,6 @@ export default class OrbitalArea {
// noop
}

/**
* Calculates the fill color of the orbital area based on the completion fraction
*/
public getColor(): Color {
// TODO: Use a color palette
// const colorPalette = [
// '#80007F',
// '#A400A4',
// '#C800C8',
// '#FF24FF',
// '#FF6DFF',
// '#FF92FF',
// ];
const fillBrightness = this.alreadyEntered ? this.insideProperty.value ? 1 : this.completion : 0;
return KeplersLawsConstants.AREA_COLOR.value.colorUtilsBrightness( Utils.linear( 0, 1, -0.8, 0.7, fillBrightness ) ).setAlpha( this.alreadyEntered ? 1 : 0 );
}


public reset(): void {
this.dotPosition = Vector2.ZERO;
this.startPosition = Vector2.ZERO;
Expand Down
4 changes: 2 additions & 2 deletions js/common/view/EllipticalOrbitNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export default class EllipticalOrbitNode extends Path {
// Set the center of the orbit's divisions dot
const dotPosition = area.dotPosition.times( scale ).minus( center );
orbitDivisions[ i ].center = dotPosition;
orbitDivisions[ i ].fill = SolarSystemCommonColors.orbitColorProperty.value.darkerColor( Math.pow( 1 - area.completion, 10 ) );
orbitDivisions[ i ].fill = KeplersLawsConstants.AREA_COLOR;

const start = area.startPosition.times( scale ).minus( center );
const end = area.endPosition.times( scale ).minus( center );
Expand All @@ -412,7 +412,7 @@ export default class EllipticalOrbitNode extends Path {
areaValueNumberDisplays[ i ].visible = areaValueProperties[ i ].value > 0;

// Activate area path
areaPaths[ i ].fill = area.getColor();
areaPaths[ i ].fill = model.getAreaColor( area ).setAlpha( area.alreadyEntered ? 1 : 0 );
areaPaths[ i ].shape = new Shape().moveTo( radiusC, 0 ).ellipticalArc(
0, 0, radiusX, radiusY, 0, startAngle, endAngle, false
).close();
Expand Down
2 changes: 1 addition & 1 deletion js/common/view/SecondLawGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class AreasBarPlot extends Node {
activeAreas.forEach( ( area, index ) => {
// Setting the color of the bar
const paintableFields: PaintableOptions = {
fill: area.getColor(),
fill: model.getAreaColor( area ),
stroke: 'black'
};
barPlot.rectangles[ index ].mutate( paintableFields );
Expand Down

0 comments on commit 25b2ea2

Please sign in to comment.