Skip to content

Commit

Permalink
Port common/ to TypeScript, see #401
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Oct 10, 2021
1 parent 6948c31 commit 66c8420
Show file tree
Hide file tree
Showing 30 changed files with 428 additions and 209 deletions.
6 changes: 4 additions & 2 deletions bending-light_en.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"simulation": true,
"phet-io": {
"validation": false
}
},
"supportsOutputJS": true,
"typescript": true
},
"eslintConfig": {
"extends": "../chipper/eslint/sim_eslintrc.js"
Expand Down Expand Up @@ -130,7 +132,7 @@

// Module loading in compilation-free (development) mode will be kicked off once strings are loaded.
// This is done in load-unbuilt-strings.js
window.phet.chipper.loadModules = () => loadURL( 'js/bending-light-main.js', 'module' );
window.phet.chipper.loadModules = () => loadURL( '../chipper/dist/bending-light/js/bending-light-main.js', 'module' );
</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const MAX_ANGLE_IN_WAVE_MODE = 3.0194;

// CIE 1931 2-angle tristimulus values, from http://cvrl.ioo.ucl.ac.uk/cmfs.htm. Maps wavelength (in nm) to an
// X,Y,Z value in the XYZ color space.
const XYZ = {
const XYZ: { [ key: number ]: { x: number, y: number, z: number } } = {
360: { x: 0.0001299, y: 0.000003917, z: 0.0006061 },
365: { x: 0.0002321, y: 0.000006965, z: 0.001086 },
370: { x: 0.0004149, y: 0.00001239, z: 0.001946 },
Expand Down Expand Up @@ -128,7 +128,7 @@ const XYZ = {
// CIE Standard Illuminant D65 relative spectral power distribution (e.g. white light wavelength distribution)
// From http://www.cie.co.at/publ/abst/datatables15_2004/sid65.txt, with wavelength < 360 removed to match our XYZ
// table. The relative values between wavelengths are what is important here.
const D65 = {
const D65: { [ key: number ]: number } = {
360: 46.6383,
365: 49.3637,
370: 52.0891,
Expand Down Expand Up @@ -228,10 +228,10 @@ const D65 = {

// {Object} - Maps wavelength (nm) to {Vector3} XYZ colorspace values multiplied times the D65 intensity. Combines
// the D65 and XYZ responses, so it contains "how bright in XYZ" each wavelength will be for white light.
const XYZ_INTENSITIES = {};
const XYZ_INTENSITIES: { [ key: number ]: Vector3 } = {};

// Cache the magnitudes as well so they don't need to be computed many times during each draw
const XYZ_INTENSITIES_MAGNITUDE = {};
const XYZ_INTENSITIES_MAGNITUDE: { [ key: number ]: number } = {};

for ( const wavelength in XYZ ) {
const intensity = D65[ wavelength ];
Expand Down Expand Up @@ -261,7 +261,7 @@ const MAX_XYZ_INTENSITY = ( () => {
// that each XYZ value is in the range [0,1]. Multiplying any entry componentwise with MAX_XYZ_INTENSITY
// will result in the original XYZ_INTENSITIES value.
const NORMALIZED_XYZ_INTENSITIES = ( () => {
const result = {};
const result: { [ key: number ]: Vector3 } = {};

for ( const wavelength in XYZ_INTENSITIES ) {
const xyz = XYZ_INTENSITIES[ wavelength ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Utils from '../../../../scenery/js/util/Utils.js';
import bendingLight from '../../bendingLight.js';
import BendingLightConstants from '../BendingLightConstants.js';
import Laser from './Laser.js';
import LightRay from './LightRay.js';
import MediumColorFactory from './MediumColorFactory.js';

// constants
Expand All @@ -23,19 +24,36 @@ const DEFAULT_LASER_DISTANCE_FROM_PIVOT = 9.225E-6;
// a good size for the units being used in the sim; used to determine the dimensions of various model objects
const CHARACTERISTIC_LENGTH = BendingLightConstants.WAVELENGTH_RED;

class BendingLightModel {
abstract class BendingLightModel {
readonly rays: LightRay[]; // Comes from ObservableArray
readonly mediumColorFactory: MediumColorFactory;
readonly modelWidth: number;
readonly modelHeight: number;
readonly allowWebGL: boolean;
readonly laserViewProperty: Property;
readonly wavelengthProperty: Property;
readonly speedProperty: Property;
private readonly indexOfRefractionProperty: Property;
readonly showNormalProperty: Property;
readonly isPlayingProperty: Property;
readonly showAnglesProperty: Property;
readonly laser: Laser;
static DEFAULT_LASER_DISTANCE_FROM_PIVOT: number;
rotationArrowAngleOffset: number | null;

/**
* @param {number} laserAngle - laser angle in radians
* @param {boolean} topLeftQuadrant - specifies whether laser in topLeftQuadrant
* @param {number} laserDistanceFromPivot - distance of laser from pivot point
* @param {Object} [properties] - additional properties to add to the property set
*/
constructor( laserAngle, topLeftQuadrant, laserDistanceFromPivot, properties ) {
constructor( laserAngle: number, topLeftQuadrant: boolean, laserDistanceFromPivot: number ) {

// @public (read-only)- list of rays in the model
this.rays = createObservableArray();

// overriden in subtypes
this.rotationArrowAngleOffset = null;

this.mediumColorFactory = new MediumColorFactory();

// dimensions of the model, guaranteed to be shown in entirety on the stage
Expand All @@ -49,7 +67,7 @@ class BendingLightModel {
this.laserViewProperty = new Property( 'ray' ); // @public, Whether the laser is Ray or Wave mode // TODO: Enumeration
this.wavelengthProperty = new Property( BendingLightConstants.WAVELENGTH_RED );
this.isPlayingProperty = new Property( true );
this.speedProperty = new Property( TimeSpeed.NORMAL );
this.speedProperty = new Property( 'normal' );
this.indexOfRefractionProperty = new Property( 1 );
this.showNormalProperty = new Property( true );
this.showAnglesProperty = new Property( false );
Expand All @@ -63,8 +81,8 @@ class BendingLightModel {
* @public
* @param {LightRay} ray - model of light ray
*/
addRay( ray ) {
this.rays.add( ray );
addRay( ray: LightRay ) {
this.rays.push( ray );
}

/**
Expand All @@ -73,9 +91,9 @@ class BendingLightModel {
*/
clearModel() {
for ( let i = 0; i < this.rays.length; i++ ) {
this.rays.get( i ).particles.clear();
this.rays[ i ].particles.clear();
}
this.rays.clear();
this.rays.length = 0;
}

/**
Expand All @@ -87,6 +105,8 @@ class BendingLightModel {
this.propagateRays();
}

abstract propagateRays(): void;

/**
* @public
* @override
Expand All @@ -111,7 +131,7 @@ class BendingLightModel {
* @param {number} cosTheta2 - cosine of reflected angle
* @returns {number}
*/
static getReflectedPower( n1, n2, cosTheta1, cosTheta2 ) {
static getReflectedPower( n1: number, n2: number, cosTheta1: number, cosTheta2: number ) {
return Math.pow( ( n1 * cosTheta1 - n2 * cosTheta2 ) / ( n1 * cosTheta1 + n2 * cosTheta2 ), 2 );
}

Expand All @@ -124,7 +144,7 @@ class BendingLightModel {
* @param {number} cosTheta2 - cosine of transmitted angle
* @returns {number}
*/
static getTransmittedPower( n1, n2, cosTheta1, cosTheta2 ) {
static getTransmittedPower( n1: number, n2: number, cosTheta1: number, cosTheta2: number ) {
return 4 * n1 * n2 * cosTheta1 * cosTheta2 / ( Math.pow( n1 * cosTheta1 + n2 * cosTheta2, 2 ) );
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import bendingLight from '../../bendingLight.js';
import BendingLightConstants from '../BendingLightConstants.js';

class DispersionFunction {
private readonly referenceIndexOfRefraction: number;
private readonly referenceWavelength: number;

/**
* @param {number} referenceIndexOfRefraction - IndexOfRefraction of medium
* @param {number} wavelength - wavelength in meters
*/
constructor( referenceIndexOfRefraction, wavelength ) {
constructor( referenceIndexOfRefraction: number, wavelength: number ) {
this.referenceIndexOfRefraction = referenceIndexOfRefraction; // @public (read-only)
this.referenceWavelength = wavelength; // @public (read-only)
}
Expand All @@ -31,7 +33,7 @@ class DispersionFunction {
* @param {number} wavelength - wavelength in meters
* @returns {number}
*/
getSellmeierValue( wavelength ) {
getSellmeierValue( wavelength: number ) {
const L2 = wavelength * wavelength;
const B1 = 1.03961212;
const B2 = 0.231792344;
Expand Down Expand Up @@ -59,7 +61,7 @@ class DispersionFunction {
* @returns {number}
* @public
*/
getIndexOfRefraction( wavelength ) {
getIndexOfRefraction( wavelength: number ) {

// get the reference values
const nAirReference = this.getAirIndex( this.referenceWavelength );
Expand All @@ -82,7 +84,7 @@ class DispersionFunction {
* @returns {number}
* @private
*/
getAirIndex( wavelength ) {
getAirIndex( wavelength: number ) {
return 1 +
5792105E-8 / ( 238.0185 - Math.pow( wavelength * 1E6, -2 ) ) +
167917E-8 / ( 57.362 - Math.pow( wavelength * 1E6, -2 ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ import bendingLight from '../../bendingLight.js';
import Reading from './Reading.js';

class IntensityMeter {
readonly readingProperty: Property;
readonly sensorPositionProperty: Vector2Property;
readonly bodyPositionProperty: Vector2Property;
private rayReadings: Reading[];
readonly enabledProperty: Property;

/**
* @param {number} sensorX - sensor x position in model coordinates
* @param {number} sensorY - sensor y position in model coordinates
* @param {number} bodyX - body x position in model coordinates
* @param {number} bodyY - body y position in model coordinates
*/
constructor( sensorX, sensorY, bodyX, bodyY ) {
constructor( sensorX: number, sensorY: number, bodyX: number, bodyY: number ) {

this.readingProperty = new Property( Reading.MISS ); // @public, value to show on the body
this.readingProperty = new Property( 'miss' ); // @public, value to show on the body
this.sensorPositionProperty = new Vector2Property( new Vector2( sensorX, sensorY ) ); // @public
this.bodyPositionProperty = new Vector2Property( new Vector2( bodyX, bodyY ) ); // @public
this.enabledProperty = new Property( false ); // @public, True if it is in the play area
Expand Down Expand Up @@ -74,15 +79,15 @@ class IntensityMeter {
*/
clearRayReadings() {
this.rayReadings = [];
this.readingProperty.set( Reading.MISS );
this.readingProperty.set( 'miss' );
}

/**
* Add a new reading to the accumulator and update the readout
* @public
* @param {Reading} r - intensity of the wave or MISS
*/
addRayReading( r ) {
addRayReading( r: Reading ) {
this.rayReadings.push( r );
this.updateReading();
}
Expand All @@ -94,7 +99,7 @@ class IntensityMeter {
updateReading() {

// enumerate the hits
const hits = [];
const hits: Reading[] = [];
this.rayReadings.forEach( rayReading => {
if ( rayReading.isHit() ) {
hits.push( rayReading );
Expand All @@ -103,13 +108,13 @@ class IntensityMeter {

// if not hits, say "MISS"
if ( hits.length === 0 ) {
this.readingProperty.set( Reading.MISS );
this.readingProperty.set( 'miss' );
}
else {

// otherwise, sum the intensities
let total = 0.0;
hits.forEach( hit => {
hits.forEach( ( hit: Reading ) => {
total += hit.value;
} );
this.readingProperty.set( new Reading( total ) );
Expand Down
17 changes: 13 additions & 4 deletions js/common/model/Laser.js → js/common/model/Laser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@ import BendingLightConstants from '../BendingLightConstants.js';
import LaserColor from '../view/LaserColor.js';

class Laser {
readonly topLeftQuadrant: boolean;
readonly onProperty: Property;
readonly waveProperty: Property;
readonly colorModeProperty: Property;
readonly emissionPointProperty: Vector2Property;
readonly colorProperty: DerivedProperty;
private readonly wavelengthProperty: Property;
private readonly directionUnitVector: Vector2;
readonly pivotProperty: Vector2Property;

/**
* @param {Property.<number>} wavelengthProperty - wavelength of light
* @param {number} distanceFromPivot - distance from laser pivot point
* @param {number} angle - laser angle
* @param {boolean} topLeftQuadrant - specifies whether laser in topLeftQuadrant
*/
constructor( wavelengthProperty, distanceFromPivot, angle, topLeftQuadrant ) {
constructor( wavelengthProperty: Property, distanceFromPivot: number, angle: number, topLeftQuadrant: boolean ) {

this.topLeftQuadrant = topLeftQuadrant;
this.pivotProperty = new Vector2Property( new Vector2( 0, 0 ) ); // @public, point to be pivoted about, and at which the laser points
Expand All @@ -33,7 +42,7 @@ class Laser {
this.emissionPointProperty = new Vector2Property( Vector2.createPolar( distanceFromPivot, angle ) ); // @public model the point where light comes out of the laser where the light comes from

// @public (read-only)
this.colorProperty = new DerivedProperty( [ wavelengthProperty ], wavelength => new LaserColor( wavelength ) );
this.colorProperty = new DerivedProperty( [ wavelengthProperty ], ( wavelength: number ) => new LaserColor( wavelength ) );

// @public (read-only)
this.wavelengthProperty = wavelengthProperty;
Expand Down Expand Up @@ -68,7 +77,7 @@ class Laser {
* @param {number} deltaX - amount of space in x direction laser to be translated
* @param {number} deltaY - amount of space in y direction laser to be translated
*/
translate( deltaX, deltaY ) {
translate( deltaX: number, deltaY: number ) {

// Caution -- For reasons unknown to @samreid, if the order of the following instructions is switched, the
// laser will rotate while being dragged, see #221
Expand All @@ -93,7 +102,7 @@ class Laser {
* @param {number} angle - angle to be rotated
* @public
*/
setAngle( angle ) {
setAngle( angle: number ) {
const distFromPivot = this.pivotProperty.value.distance( this.emissionPointProperty.value );
this.emissionPointProperty.value = new Vector2(
distFromPivot * Math.cos( angle ) + this.pivotProperty.value.x,
Expand Down
Loading

0 comments on commit 66c8420

Please sign in to comment.