From ff1c1c3c8b452735cf7feed4b0e84db0f5300588 Mon Sep 17 00:00:00 2001 From: jbphet Date: Mon, 9 Dec 2024 17:00:00 -0700 Subject: [PATCH] use a dyanamic set of positional states, see https://github.com/phetsims/quantum-measurement/issues/65 --- js/photons/model/Laser.ts | 18 +- js/photons/model/Mirror.ts | 13 +- js/photons/model/Photon.ts | 202 ++++++++---------- js/photons/model/PhotonDetector.ts | 20 +- js/photons/model/PhotonMotionState.ts | 75 +++++++ .../model/PhotonsExperimentSceneModel.ts | 23 +- js/photons/model/PolarizingBeamSplitter.ts | 14 +- js/photons/model/TPhotonInteraction.ts | 5 +- js/photons/view/PhotonSprites.ts | 8 +- 9 files changed, 203 insertions(+), 175 deletions(-) create mode 100644 js/photons/model/PhotonMotionState.ts diff --git a/js/photons/model/Laser.ts b/js/photons/model/Laser.ts index 05a0897..70a90c9 100644 --- a/js/photons/model/Laser.ts +++ b/js/photons/model/Laser.ts @@ -18,7 +18,7 @@ import PickRequired from '../../../../phet-core/js/types/PickRequired.js'; import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js'; import StringUnionIO from '../../../../tandem/js/types/StringUnionIO.js'; import quantumMeasurement from '../../quantumMeasurement.js'; -import Photon, { PHOTON_SPEED, QuantumPossibleState, RIGHT } from './Photon.js'; +import Photon, { PHOTON_SPEED, RIGHT } from './Photon.js'; import { PhotonCollection } from './PhotonCollection.js'; export type PhotonEmissionMode = 'singlePhoton' | 'manyPhotons'; @@ -146,20 +146,8 @@ export default class Laser { const photon = new Photon( polarizationAngle, - { - vertical: new QuantumPossibleState( - this.position.plusXY( xOffset, yOffset ), - this.emissionDirection, - 1, - 'vertical' - ), - horizontal: new QuantumPossibleState( - this.position.plusXY( xOffset, yOffset ), - this.emissionDirection, - 0, - 'horizontal' - ) - } + this.position.plusXY( xOffset, yOffset ), + this.emissionDirection ); this.photonCollection.addPhoton( photon ); diff --git a/js/photons/model/Mirror.ts b/js/photons/model/Mirror.ts index f07f8b5..e3a381b 100644 --- a/js/photons/model/Mirror.ts +++ b/js/photons/model/Mirror.ts @@ -13,7 +13,8 @@ import { EmptySelfOptions } from '../../../../phet-core/js/optionize.js'; import PickRequired from '../../../../phet-core/js/types/PickRequired.js'; import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js'; import quantumMeasurement from '../../quantumMeasurement.js'; -import Photon, { DOWN, PossiblePolarizationResult, QuantumPossibleState } from './Photon.js'; +import Photon, { DOWN } from './Photon.js'; +import { PhotonMotionState } from './PhotonMotionState.js'; import { PhotonInteractionTestResult } from './PhotonsModel.js'; import { TPhotonInteraction } from './TPhotonInteraction.js'; @@ -40,16 +41,14 @@ export default class Mirror implements TPhotonInteraction { this.mirrorSurfaceLine = new Line( endpoint1, endpoint2 ); } - public testForPhotonInteraction( photon: Photon, dt: number ): Map { + public testForPhotonInteraction( photon: Photon, dt: number ): Map { - const mapOfStatesToInteractions = new Map(); + const mapOfStatesToInteractions = new Map(); // Iterate over the possible states and test for interactions. - Object.keys( photon.possibleStates ).forEach( stateKey => { + photon.possibleMotionStates.forEach( photonState => { - const photonState = photon.possibleStates[ stateKey as PossiblePolarizationResult ]; - - // Test for whether this photon crosses the surface of the beam splitter. + // Test whether this photon state would reach the surface of the mirror in the provided time. const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint( this.mirrorSurfaceLine.start, this.mirrorSurfaceLine.end, diff --git a/js/photons/model/Photon.ts b/js/photons/model/Photon.ts index d97d94f..bd59e75 100644 --- a/js/photons/model/Photon.ts +++ b/js/photons/model/Photon.ts @@ -7,12 +7,12 @@ * @author John Blanco, PhET Interactive Simulations */ -import Utils from '../../../../dot/js/Utils.js'; -import Vector2, { Vector2StateObject } from '../../../../dot/js/Vector2.js'; +import Vector2 from '../../../../dot/js/Vector2.js'; +import ArrayIO from '../../../../tandem/js/types/ArrayIO.js'; import IOType from '../../../../tandem/js/types/IOType.js'; import NumberIO from '../../../../tandem/js/types/NumberIO.js'; -import StringIO from '../../../../tandem/js/types/StringIO.js'; import quantumMeasurement from '../../quantumMeasurement.js'; +import { PhotonMotionState } from './PhotonMotionState.js'; export const PHOTON_SPEED = 0.3; // meters per second @@ -26,115 +26,93 @@ export const RIGHT = new Vector2( 1, 0 ); // the resulting states will either be measured as vertical or horizontal. export type PossiblePolarizationResult = 'vertical' | 'horizontal'; -// TODO: This class could live in its own file, once the feature is fully green lit, will move https://github.com/phetsims/quantum-measurement/issues/63 -/** - * QuantumPossibleState is a class that represents a possible state of a photon at a given point in time. - * It contains variables for position, direction and the probability of the photon being in that state. - */ -export class QuantumPossibleState { - public constructor( public position: Vector2, - public direction: Vector2, - public probability: number, - public readonly polarization: PossiblePolarizationResult /* TODO this still needed? https://github.com/phetsims/quantum-measurement/issues/65 */ ) { - // no-op +export default class Photon { + + // the angle of polarization for this photon, in degrees + public polarizationAngle: number; + + // Contains all the possible motion states of the photon. The photon should always have at least one of these, but + // can have more than one if it is in a superposition of states. The probabilities of these states should always add + // up to 1. This array can be monitored outside of this class, but should only be modified through the methods. + public readonly possibleMotionStates: PhotonMotionState[]; + + public constructor( polarizationAngle: number, + initialPosition: Vector2, + initialDirection: Vector2 ) { + + this.polarizationAngle = polarizationAngle; + + // Start off with a single possible motion state for the photon. + this.possibleMotionStates = [ new PhotonMotionState( initialPosition, initialDirection, 1 ) ]; } /** - * Get the point where this photon would intersect the provided line segment if it were to move for the specified - * amount of time. Returns null if the photon would not intersect the line segment. - * @param lineStart - * @param lineEnd - * @param dt - time step, in seconds + * Add a new motion state to the photon. The probability of the new state should be provided, and the probability of + * the existing state will be adjusted accordingly. The probabilities of all states should always add up to 1. */ - public getTravelPathIntersectionPoint( lineStart: Vector2, lineEnd: Vector2, dt: number ): Vector2 | null { - - // Create a line that represents the path of the photon. - const photonPathEndPoint = this.position.plus( this.direction.timesScalar( PHOTON_SPEED * dt ) ); - - // Return the intersection point if there is one, null if not. - return Utils.lineSegmentIntersection( - this.position.x, - this.position.y, - photonPathEndPoint.x, - photonPathEndPoint.y, - lineStart.x, - lineStart.y, - lineEnd.x, - lineEnd.y - ); - } + public addMotionState( position: Vector2, direction: Vector2, probability: number ): void { - public step( dt: number ): void { - this.position = this.position.plus( this.direction.timesScalar( PHOTON_SPEED * dt ) ); - } + // As of this writing, only two possible motion states are allowed. + assert && assert( this.possibleMotionStates.length < 2, 'Only two possible motion states are allowed.' ); - public static readonly QuantumPossibleStateIO = new IOType( 'QuantumPossibleStateIO', { - valueType: QuantumPossibleState, - stateSchema: { - position: Vector2.Vector2IO, - direction: Vector2.Vector2IO, - probability: NumberIO, - polarization: StringIO - }, - fromStateObject: ( stateObject: QuantumPossibleStateStateObject ) => { - return new QuantumPossibleState( - Vector2.Vector2IO.fromStateObject( stateObject.position ), - Vector2.Vector2IO.fromStateObject( stateObject.direction ), - stateObject.probability, - stateObject.polarization as PossiblePolarizationResult - ); + // Make sure the probabilities add up to 1. + if ( this.possibleMotionStates.length === 1 ) { + const existingMotionState = this.possibleMotionStates[ 0 ]; + existingMotionState.probability = 1 - probability; } - } ); -} + else { -export default class Photon { + // If this is the only state, make sure the probability is 1. + assert && assert( probability === 1, 'The probability should be 1 for the first state.' ); + } - // the angle of polarization for this photon, in degrees - public polarizationAngle: number; + // Add the new motion state. + this.possibleMotionStates.push( new PhotonMotionState( position, direction, probability ) ); + } - // Contains all the possible states of the photon, which include position, direction, and probability. - // Since they contain properties, and based on the design of this simulation, it will always have two states. - public possibleStates: TwoStateQuantumPossibleState; + /** + * Remove a motion state from the photon. The probability of the remaining state will be adjusted accordingly. The + * probabilities of all states should always add up to 1. + */ + public removeMotionState( motionState: PhotonMotionState ): void { + const index = this.possibleMotionStates.indexOf( motionState ); + assert && assert( index !== -1, 'Motion state not found.' ); - public constructor( polarizationAngle: number, - possibleStates: TwoStateQuantumPossibleState ) { + // Remove the motion state. + this.possibleMotionStates.splice( index, 1 ); - this.polarizationAngle = polarizationAngle; - this.possibleStates = possibleStates; + // Make sure there is at least one state left. + assert && assert( this.possibleMotionStates.length > 0, 'At least one motion state is needed for the photon.' ); + + // Adjust the probability of the remaining state. As of this writing, only two states are allowed. + this.possibleMotionStates[ 0 ].probability = 1; } - public setCorrespondingProbability( providedState: QuantumPossibleState, probability: number ): void { - const providedStateKey = _.findKey( this.possibleStates, providedState ) as PossiblePolarizationResult; + /** + * Set the probability of a motion state. The probability of the other state, if present, will be adjusted + * accordingly. + */ + public setMotionStateProbability( motionState: PhotonMotionState, probability: number ): void { - assert && assert( providedStateKey, 'Photon state not found!' ); + // parameter and state checking + assert && assert( probability >= 0 && probability <= 1, 'Probability must be between 0 and 1.' ); + assert && assert( this.possibleMotionStates.length <= 2, 'A max of 2 motion states are currently supported.' ); - const correspondingKey = providedStateKey === 'vertical' ? 'horizontal' : 'vertical'; - const correspondingState = this.possibleStates[ correspondingKey ]; + const index = this.possibleMotionStates.indexOf( motionState ); + assert && assert( index !== -1, 'Motion state not found.' ); + this.possibleMotionStates[ index ].probability = probability; - providedState.probability = probability; - correspondingState.probability = 1 - probability; + // If there are two states, adjust the probability of the other state. + if ( this.possibleMotionStates.length === 2 ) { + const otherMotionState = this.possibleMotionStates[ 1 - index ]; + otherMotionState.probability = 1 - probability; + } } public step( dt: number ): void { - for ( const key in this.possibleStates ) { - this.possibleStates[ key as PossiblePolarizationResult ].step( dt ); - } + this.possibleMotionStates.forEach( state => state.step( dt ) ); } - public static readonly TwoStateQuantumPossibleStateIO = new IOType( 'TwoStateQuantumPossibleStateIO', { - valueType: Photon, - stateSchema: { - vertical: QuantumPossibleState.QuantumPossibleStateIO, - horizontal: QuantumPossibleState.QuantumPossibleStateIO - }, - fromStateObject: ( stateObject: TwoStateQuantumPossibleStateStateObject ) => { - return { - vertical: QuantumPossibleState.QuantumPossibleStateIO.fromStateObject( stateObject.vertical ), - horizontal: QuantumPossibleState.QuantumPossibleStateIO.fromStateObject( stateObject.horizontal ) - }; - } - } ); - /** * Individual Projectile instances are not PhET-iO Instrumented. Instead, the Field that contains the Projectiles * calls ProjectileIO.toStateObject to serialize the Projectile instances. FieldIO uses reference type serialization @@ -147,40 +125,36 @@ export default class Photon { valueType: Photon, stateSchema: { polarizationAngle: NumberIO, - possibleStates: Photon.TwoStateQuantumPossibleStateIO + possibleMotionStates: ArrayIO( PhotonMotionState.PhotonMotionStateIO ) }, fromStateObject: ( stateObject: PhotonStateObject ) => { - return new Photon( + + assert && assert( stateObject.possibleMotionStates.length > 0, 'There must be at least one motion state.' ); + + const photon = new Photon( stateObject.polarizationAngle, - { - vertical: QuantumPossibleState.QuantumPossibleStateIO.fromStateObject( stateObject.possibleStates.vertical ), - horizontal: QuantumPossibleState.QuantumPossibleStateIO.fromStateObject( stateObject.possibleStates.horizontal ) - } + Vector2.fromStateObject( stateObject.possibleMotionStates[ 0 ].position ), + Vector2.fromStateObject( stateObject.possibleMotionStates[ 0 ].direction ) ); + + // Add the remaining motion states, if any. + for ( let i = 1; i < stateObject.possibleMotionStates.length; i++ ) { + const motionStateStateObject = stateObject.possibleMotionStates[ i ]; + photon.addMotionState( + Vector2.fromStateObject( motionStateStateObject.position ), + Vector2.fromStateObject( motionStateStateObject.direction ), + motionStateStateObject.probability + ); + } + + return photon; } } ); } -type TwoStateQuantumPossibleState = { - vertical: QuantumPossibleState; - horizontal: QuantumPossibleState; -}; - -type TwoStateQuantumPossibleStateStateObject = { - vertical: QuantumPossibleStateStateObject; - horizontal: QuantumPossibleStateStateObject; -}; - export type PhotonStateObject = { polarizationAngle: number; - possibleStates: TwoStateQuantumPossibleStateStateObject; -}; - -export type QuantumPossibleStateStateObject = { - position: Vector2StateObject; - direction: Vector2StateObject; - probability: number; - polarization: string; + possibleMotionStates: PhotonMotionState[]; }; quantumMeasurement.register( 'Photon', Photon ); \ No newline at end of file diff --git a/js/photons/model/PhotonDetector.ts b/js/photons/model/PhotonDetector.ts index 4ff57ca..31c3df1 100644 --- a/js/photons/model/PhotonDetector.ts +++ b/js/photons/model/PhotonDetector.ts @@ -18,7 +18,8 @@ import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js'; import AveragingCounterNumberProperty from '../../common/model/AveragingCounterNumberProperty.js'; import quantumMeasurement from '../../quantumMeasurement.js'; import { PHOTON_BEAM_WIDTH } from './Laser.js'; -import Photon, { PossiblePolarizationResult, QuantumPossibleState } from './Photon.js'; +import Photon from './Photon.js'; +import { PhotonMotionState } from './PhotonMotionState.js'; import { PhotonInteractionTestResult } from './PhotonsModel.js'; import { TPhotonInteraction } from './TPhotonInteraction.js'; @@ -88,16 +89,14 @@ export default class PhotonDetector implements TPhotonInteraction { } ); } - public testForPhotonInteraction( photon: Photon, dt: number ): Map { + public testForPhotonInteraction( photon: Photon, dt: number ): Map { - const mapOfStatesToInteractions = new Map(); + const mapOfStatesToInteractions = new Map(); // Iterate over the possible states and test for interactions. - Object.keys( photon.possibleStates ).forEach( stateKey => { + photon.possibleMotionStates.forEach( photonState => { - const photonState = photon.possibleStates[ stateKey as PossiblePolarizationResult ]; - - // Test for whether this photon would cross the detection aperture. + // Test whether this photon state would reach or cross the detection aperture in the provided time. const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint( this.detectionLine.start, this.detectionLine.end, @@ -110,16 +109,16 @@ export default class PhotonDetector implements TPhotonInteraction { // This is where the wave function collapses! if ( photonIntersectionPoint !== null ) { - // Evaluate the detection result based on the probability of the photon actually being here! + // Evaluate the detection result based on the probability of the photon actually being here. if ( dotRandom.nextDouble() < photonState.probability ) { - photon.setCorrespondingProbability( photonState, 1 ); + photon.setMotionStateProbability( photonState, 1 ); photonState.probability = 1; // the photon is detected! interaction = { interactionType: 'absorbed' }; } else { // If the photon is not detected. This state probability goes to 0%, which will make the other state 100%. - photon.setCorrespondingProbability( photonState, 0 ); + photon.setMotionStateProbability( photonState, 0 ); } } @@ -134,7 +133,6 @@ export default class PhotonDetector implements TPhotonInteraction { return mapOfStatesToInteractions; } - public step( dt: number ): void { this.detectionRateProperty.step( dt ); } diff --git a/js/photons/model/PhotonMotionState.ts b/js/photons/model/PhotonMotionState.ts new file mode 100644 index 0000000..6dfa190 --- /dev/null +++ b/js/photons/model/PhotonMotionState.ts @@ -0,0 +1,75 @@ +// Copyright 2024, University of Colorado Boulder + +/** + * PhotonMotionState is a class that represents a possible state of a photon's motion. It contains variables for + * position, direction, and the probability of the photon being in that state. + * + * @author Agustín Vallejo (PhET Interactive Simulations) + * * @author John Blanco (PhET Interactive Simulations) + */ + +import Utils from '../../../../dot/js/Utils.js'; +import Vector2, { Vector2StateObject } from '../../../../dot/js/Vector2.js'; +import IOType from '../../../../tandem/js/types/IOType.js'; +import NumberIO from '../../../../tandem/js/types/NumberIO.js'; +import { PHOTON_SPEED } from './Photon.js'; + +export class PhotonMotionState { + + public constructor( public position: Vector2, + public direction: Vector2, + public probability: number ) { + // no-op + } + + /** + * Get the point where this photon would intersect the provided line segment if it were to move for the specified + * amount of time. Returns null if the photon would not intersect the line segment. + * @param lineStart + * @param lineEnd + * @param dt - time step, in seconds + */ + public getTravelPathIntersectionPoint( lineStart: Vector2, lineEnd: Vector2, dt: number ): Vector2 | null { + + // Create a line that represents the path of the photon. + const photonPathEndPoint = this.position.plus( this.direction.timesScalar( PHOTON_SPEED * dt ) ); + + // Return the intersection point if there is one, null if not. + return Utils.lineSegmentIntersection( + this.position.x, + this.position.y, + photonPathEndPoint.x, + photonPathEndPoint.y, + lineStart.x, + lineStart.y, + lineEnd.x, + lineEnd.y + ); + } + + public step( dt: number ): void { + this.position = this.position.plus( this.direction.timesScalar( PHOTON_SPEED * dt ) ); + } + + public static readonly PhotonMotionStateIO = new IOType( 'PhotonMotionStateIO', { + valueType: PhotonMotionState, + stateSchema: { + position: Vector2.Vector2IO, + direction: Vector2.Vector2IO, + probability: NumberIO + }, + fromStateObject: ( stateObject: PhotonMotionStateStateObject ) => { + return new PhotonMotionState( + Vector2.fromStateObject( stateObject.position ), + Vector2.fromStateObject( stateObject.direction ), + stateObject.probability + ); + } + } ); +} + +export type PhotonMotionStateStateObject = { + position: Vector2StateObject; + direction: Vector2StateObject; + probability: number; +}; \ No newline at end of file diff --git a/js/photons/model/PhotonsExperimentSceneModel.ts b/js/photons/model/PhotonsExperimentSceneModel.ts index 41009a8..5361c99 100644 --- a/js/photons/model/PhotonsExperimentSceneModel.ts +++ b/js/photons/model/PhotonsExperimentSceneModel.ts @@ -246,28 +246,23 @@ export default class PhotonsExperimentSceneModel { if ( interaction.interactionType === 'split' ) { assert && assert( interaction.splitInfo, 'split info missing' ); + assert && assert( photon.possibleMotionStates.length === 1, 'there should be 1 motion state' ); - // The resulting interaction was a split of the photon state. First step the state to the split point. + // The resulting interaction was a split of the photon state. First, step the state to the split point. const dtToSplitPoint = photonState.position.distance( interaction.splitInfo!.splitPoint ) / PHOTON_SPEED; assert && assert( dtToSplitPoint <= dt ); photonState.step( dtToSplitPoint ); - // Update the state based on the first split info element. + // Update the existing motion state based on the first split info element. photonState.direction = interaction.splitInfo!.splitStates[ 0 ].direction; photonState.probability = interaction.splitInfo!.splitStates[ 0 ].probability; - // Update the other state based on the second split info element. - // TODO: This will get more reasonable when the quantum states are an array. See https://github.com/phetsims/quantum-measurement/issues/65. - if ( photon.possibleStates.vertical === photonState ) { - photon.possibleStates.horizontal.direction = interaction.splitInfo!.splitStates[ 1 ].direction; - photon.possibleStates.horizontal.probability = interaction.splitInfo!.splitStates[ 1 ].probability; - photon.possibleStates.horizontal.position = photonState.position; - } - else { - photon.possibleStates.vertical.direction = interaction.splitInfo!.splitStates[ 1 ].direction; - photon.possibleStates.vertical.probability = interaction.splitInfo!.splitStates[ 1 ].probability; - photon.possibleStates.vertical.position = photonState.position; - } + // Add a new state to the photon for the second split info element. + photon.addMotionState( + photonState.position, + interaction.splitInfo!.splitStates[ 1 ].direction, + interaction.splitInfo!.splitStates[ 1 ].probability + ); } else if ( interaction.interactionType === 'absorbed' ) { diff --git a/js/photons/model/PolarizingBeamSplitter.ts b/js/photons/model/PolarizingBeamSplitter.ts index d162fee..5b2c92c 100644 --- a/js/photons/model/PolarizingBeamSplitter.ts +++ b/js/photons/model/PolarizingBeamSplitter.ts @@ -16,7 +16,8 @@ import { Line } from '../../../../kite/js/imports.js'; import PickRequired from '../../../../phet-core/js/types/PickRequired.js'; import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js'; import quantumMeasurement from '../../quantumMeasurement.js'; -import Photon, { PossiblePolarizationResult, QuantumPossibleState, RIGHT, UP } from './Photon.js'; +import Photon, { RIGHT, UP } from './Photon.js'; +import { PhotonMotionState } from './PhotonMotionState.js'; import { PhotonInteractionTestResult } from './PhotonsModel.js'; import { TPhotonInteraction } from './TPhotonInteraction.js'; @@ -49,23 +50,20 @@ export default class PolarizingBeamSplitter implements TPhotonInteraction { this.polarizingSurfaceLine = new Line( endpoint1, endpoint2 ); } - public testForPhotonInteraction( photon: Photon, dt: number ): Map { + public testForPhotonInteraction( photon: Photon, dt: number ): Map { - // TODO: Add an assertion to make sure there is at least one state, see https://github.com/phetsims/quantum-measurement/issues/65. - const mapOfStatesToInteractions = new Map(); + const mapOfStatesToInteractions = new Map(); // Iterate over the possible states and test for interactions. - Object.keys( photon.possibleStates ).forEach( stateKey => { - const photonState = photon.possibleStates[ stateKey as PossiblePolarizationResult ]; + photon.possibleMotionStates.forEach( photonState => { - // Test for whether this photon crosses the surface of the beam splitter. + // Test whether this photon state reaches or crosses the surface of the beam splitter. const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint( this.polarizingSurfaceLine.start, this.polarizingSurfaceLine.end, dt ); - // Assume no interaction until proven otherwise. let interaction: PhotonInteractionTestResult = { interactionType: 'none' }; if ( photonIntersectionPoint !== null ) { diff --git a/js/photons/model/TPhotonInteraction.ts b/js/photons/model/TPhotonInteraction.ts index 0d71ded..2ffe25b 100644 --- a/js/photons/model/TPhotonInteraction.ts +++ b/js/photons/model/TPhotonInteraction.ts @@ -6,9 +6,10 @@ * @author John Blanco, PhET Interactive Simulations */ -import Photon, { QuantumPossibleState } from './Photon.js'; +import Photon from './Photon.js'; +import { PhotonMotionState } from './PhotonMotionState.js'; import { PhotonInteractionTestResult } from './PhotonsModel.js'; export type TPhotonInteraction = { - testForPhotonInteraction( photon: Photon, dt: number ): Map; + testForPhotonInteraction( photon: Photon, dt: number ): Map; }; \ No newline at end of file diff --git a/js/photons/view/PhotonSprites.ts b/js/photons/view/PhotonSprites.ts index d7aa82b..0b9ef2e 100644 --- a/js/photons/view/PhotonSprites.ts +++ b/js/photons/view/PhotonSprites.ts @@ -82,11 +82,11 @@ export default class PhotonSprites extends Sprites { const photon = this.photons[ i ]; // Iterate over the two possible photon states - for ( const photonState of Object.values( photon.possibleStates ) ) { + for ( const photonMotionState of photon.possibleMotionStates ) { - if ( photonState.probability > 0 ) { + if ( photonMotionState.probability > 0 ) { numberOfPhotonsDisplayed++; - const photonStatePosition = photonState.position; + const photonStatePosition = photonMotionState.position; // Add a new sprite instance to our list if we don't have enough. if ( numberOfPhotonsDisplayed > this.spriteInstances.length ) { @@ -106,7 +106,7 @@ export default class PhotonSprites extends Sprites { this.photonScale, this.modelViewTransform.modelToViewY( photonStatePosition.y ) ); - spriteInstance.alpha = photonState.probability; // Probability based opacity + spriteInstance.alpha = photonMotionState.probability; // Probability based opacity } } }