-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Depict superposed states for photons on the "Photons" screen #65
Comments
Here's a patch of that functionality in place. I don't want to commit before reviewing thoroughly with @jbphet Subject: [PATCH] Potential approach at showing the different photon states
---
Index: js/photons/model/Photon.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/Photon.ts b/js/photons/model/Photon.ts
--- a/js/photons/model/Photon.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/Photon.ts (date 1733176580492)
@@ -24,54 +24,19 @@
export const LEFT = new Vector2( -1, 0 );
export const RIGHT = new Vector2( 1, 0 );
-export default class Photon extends PhetioObject {
+type possiblePolarizationResult = 'vertical' | 'horizontal';
- // position in 2D space
+export class PhotonState {
public readonly positionProperty: Vector2Property;
-
- // a unit vector that represents the direction of travel for this photon
public readonly directionProperty: Vector2Property;
-
- // whether this photon is active, and should thus be moved by the model and shown in the view
- public readonly activeProperty: BooleanProperty;
+ public readonly probabilityProperty: NumberProperty;
+ public readonly polarization: possiblePolarizationResult;
- // the angle of polarization for this photon, in degrees
- public readonly polarizationAngleProperty: NumberProperty;
-
- public constructor( tandem: Tandem ) {
-
- super( {
- tandem: tandem,
- phetioState: false
- } );
-
- this.positionProperty = new Vector2Property( Vector2.ZERO, {
- tandem: tandem.createTandem( 'positionProperty' )
- } );
-
- this.polarizationAngleProperty = new NumberProperty( 0, {
- tandem: tandem.createTandem( 'polarizationAngleProperty' )
- } );
-
- this.directionProperty = new Vector2Property( RIGHT, {
- tandem: tandem.createTandem( 'directionProperty' )
- } );
-
- this.activeProperty = new BooleanProperty( false, {
- tandem: tandem.createTandem( 'activeProperty' )
- } );
- }
-
- public step( dt: number ): void {
- if ( this.activeProperty.value ) {
- this.positionProperty.set( this.positionProperty.value.plus( this.directionProperty.value.timesScalar( PHOTON_SPEED * dt ) ) );
- }
- }
-
- public reset(): void {
- this.positionProperty.reset();
- this.directionProperty.reset();
- this.activeProperty.reset();
+ public constructor( polarization: possiblePolarizationResult ) {
+ this.positionProperty = new Vector2Property( Vector2.ZERO );
+ this.directionProperty = new Vector2Property( RIGHT );
+ this.probabilityProperty = new NumberProperty( polarization === 'vertical' ? 1 : 0 );
+ this.polarization = polarization;
}
/**
@@ -98,6 +63,72 @@
lineEnd.y
);
}
+
+ public step( dt: number ): void {
+ this.positionProperty.set( this.positionProperty.value.plus( this.directionProperty.value.timesScalar( PHOTON_SPEED * dt ) ) );
+ }
+}
+
+export default class Photon extends PhetioObject {
+
+ // 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: [ PhotonState, PhotonState ];
+
+ // whether this photon is active, and should thus be moved by the model and shown in the view
+ public readonly activeProperty: BooleanProperty;
+
+ // the angle of polarization for this photon, in degrees
+ public readonly polarizationAngleProperty: NumberProperty;
+
+ public constructor( tandem: Tandem ) {
+
+ super( {
+ tandem: tandem,
+ phetioState: false
+ } );
+
+ this.polarizationAngleProperty = new NumberProperty( 0, {
+ tandem: tandem.createTandem( 'polarizationAngleProperty' )
+ } );
+
+ this.activeProperty = new BooleanProperty( false, {
+ tandem: tandem.createTandem( 'activeProperty' )
+ } );
+
+ this.possibleStates = [
+ new PhotonState( 'vertical' ),
+ new PhotonState( 'horizontal' )
+ ];
+
+ // Entangle the possible states
+ this.possibleStates[ 0 ].probabilityProperty.lazyLink( probability => {
+ this.possibleStates[ 1 ].probabilityProperty.set( 1 - probability );
+ } );
+ this.possibleStates[ 1 ].probabilityProperty.lazyLink( probability => {
+ this.possibleStates[ 0 ].probabilityProperty.set( 1 - probability );
+ } );
+
+ }
+
+ public step( dt: number ): void {
+ if ( this.activeProperty.value ) {
+ // this.positionProperty.set( this.positionProperty.value.plus( this.directionProperty.value.timesScalar( PHOTON_SPEED * dt ) ) );
+ this.possibleStates.forEach( state => {
+ state.step( dt );
+ } );
+ }
+ }
+
+ public reset(): void {
+ this.activeProperty.reset();
+ this.possibleStates.forEach( state => {
+ state.positionProperty.reset();
+ state.directionProperty.reset();
+ state.probabilityProperty.reset();
+ } );
+ }
}
quantumMeasurement.register( 'Photon', Photon );
\ No newline at end of file
Index: js/photons/view/PhotonSprites.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/view/PhotonSprites.ts b/js/photons/view/PhotonSprites.ts
--- a/js/photons/view/PhotonSprites.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/view/PhotonSprites.ts (date 1733174423230)
@@ -77,36 +77,40 @@
let numberOfPhotonsDisplayed = 0;
- // TODO REVIEW: Wouldn't it be better to filter first the active photons and then iterate over them? https://github.com/phetsims/quantum-measurement/issues/52
- for ( let i = 0; i < this.photons.length; i++ ) {
+ const activePhotons = this.photons.filter( photon => photon.activeProperty.value );
+
+ for ( let i = 0; i < activePhotons.length; i++ ) {
- // Convenience constants.
- const photon = this.photons[ i ];
- const photonPosition = photon.positionProperty.value;
+ const photon = activePhotons[ i ];
- // Only display active photons.
- if ( photon.activeProperty.value ) {
+ for ( let j = 0; j < 2; j++ ) {
- numberOfPhotonsDisplayed++;
+ const photonState = photon.possibleStates[ j ];
+
+ if ( photonState.probabilityProperty.value > 0 ) {
+ numberOfPhotonsDisplayed++;
+ const photonStatePosition = photonState.positionProperty.value;
- // Add a new sprite instance to our list if we don't have enough.
- if ( numberOfPhotonsDisplayed > this.spriteInstances.length ) {
- const newSpriteInstance = SpriteInstance.pool.fetch();
- newSpriteInstance.transformType = SpriteInstanceTransformType.AFFINE;
- this.spriteInstances.push( newSpriteInstance );
- }
+ // Add a new sprite instance to our list if we don't have enough.
+ if ( numberOfPhotonsDisplayed > this.spriteInstances.length ) {
+ const newSpriteInstance = SpriteInstance.pool.fetch();
+ newSpriteInstance.transformType = SpriteInstanceTransformType.AFFINE;
+ this.spriteInstances.push( newSpriteInstance );
+ }
- // Update the matrix that controls where this photon is rendered.
- const spriteInstance = this.spriteInstances[ numberOfPhotonsDisplayed - 1 ];
- spriteInstance.sprite = this.photonSprite;
- spriteInstance.matrix.setToAffine(
- this.photonScale,
- 0,
- this.modelViewTransform.modelToViewX( photonPosition.x ),
- 0,
- this.photonScale,
- this.modelViewTransform.modelToViewY( photonPosition.y )
- );
+ // Update the matrix that controls where this photon is rendered.
+ const spriteInstance = this.spriteInstances[ numberOfPhotonsDisplayed - 1 ];
+ spriteInstance.sprite = this.photonSprite;
+ spriteInstance.matrix.setToAffine(
+ this.photonScale,
+ 0,
+ this.modelViewTransform.modelToViewX( photonStatePosition.x ),
+ 0,
+ this.photonScale,
+ this.modelViewTransform.modelToViewY( photonStatePosition.y )
+ );
+ spriteInstance.alpha = photonState.probabilityProperty.value;
+ }
}
}
Index: js/photons/model/Mirror.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/Mirror.ts b/js/photons/model/Mirror.ts
--- a/js/photons/model/Mirror.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/Mirror.ts (date 1733172543471)
@@ -13,7 +13,7 @@
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import quantumMeasurement from '../../quantumMeasurement.js';
-import Photon, { DOWN } from './Photon.js';
+import Photon, { DOWN, PhotonState } from './Photon.js';
import { PhotonInteractionTestResult } from './PhotonsModel.js';
import { TPhotonInteraction } from './TPhotonInteraction.js';
@@ -40,12 +40,12 @@
this.mirrorSurfaceLine = new Line( endpoint1, endpoint2 );
}
- public testForPhotonInteraction( photon: Photon, dt: number ): PhotonInteractionTestResult {
+ public testForPhotonStateInteraction( photonState: PhotonState, photon: Photon, dt: number ): PhotonInteractionTestResult {
assert && assert( photon.activeProperty.value, 'save CPU cycles - don\'t use this method with inactive photons' );
// Test for whether this photon crosses the surface of the beam splitter.
- const photonIntersectionPoint = photon.getTravelPathIntersectionPoint(
+ const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint(
this.mirrorSurfaceLine.start,
this.mirrorSurfaceLine.end,
dt
Index: js/photons/model/TPhotonInteraction.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/TPhotonInteraction.ts b/js/photons/model/TPhotonInteraction.ts
--- a/js/photons/model/TPhotonInteraction.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/TPhotonInteraction.ts (date 1733172890967)
@@ -6,9 +6,9 @@
* @author John Blanco, PhET Interactive Simulations
*/
-import Photon from './Photon.js';
+import Photon, { PhotonState } from './Photon.js';
import { PhotonInteractionTestResult } from './PhotonsModel.js';
export type TPhotonInteraction = {
- testForPhotonInteraction( photon: Photon, dt: number ): PhotonInteractionTestResult;
+ testForPhotonStateInteraction( state: PhotonState, photon: Photon, dt: number ): PhotonInteractionTestResult;
};
\ No newline at end of file
Index: js/photons/model/PolarizingBeamSplitter.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/PolarizingBeamSplitter.ts b/js/photons/model/PolarizingBeamSplitter.ts
--- a/js/photons/model/PolarizingBeamSplitter.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/PolarizingBeamSplitter.ts (date 1733176527293)
@@ -8,7 +8,6 @@
*/
import Dimension2 from '../../../../dot/js/Dimension2.js';
-import dotRandom from '../../../../dot/js/dotRandom.js';
import Utils from '../../../../dot/js/Utils.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import { Line } from '../../../../kite/js/imports.js';
@@ -16,7 +15,7 @@
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import quantumMeasurement from '../../quantumMeasurement.js';
-import Photon, { UP } from './Photon.js';
+import Photon, { PhotonState, RIGHT, UP } from './Photon.js';
import { PhotonInteractionTestResult } from './PhotonsModel.js';
import { TPhotonInteraction } from './TPhotonInteraction.js';
@@ -43,12 +42,12 @@
this.polarizingSurfaceLine = new Line( endpoint1, endpoint2 );
}
- public testForPhotonInteraction( photon: Photon, dt: number ): PhotonInteractionTestResult {
+ public testForPhotonStateInteraction( photonState: PhotonState, photon: Photon, dt: number ): PhotonInteractionTestResult {
assert && assert( photon.activeProperty.value, 'save CPU cycles - don\'t use this method with inactive photons' );
// Test for whether this photon crosses the surface of the beam splitter.
- const photonIntersectionPoint = photon.getTravelPathIntersectionPoint(
+ const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint(
this.polarizingSurfaceLine.start,
this.polarizingSurfaceLine.end,
dt
@@ -59,19 +58,23 @@
if ( photonIntersectionPoint !== null ) {
+ if ( photon.possibleStates[ 1 ].probabilityProperty.value === 0 ) {
+ // Prepare the second state position, for its probability will now be >0 and will become relevant
+ photon.possibleStates[ 1 ].positionProperty.value = photonState.positionProperty.value;
+ }
+
// Calculate the probability of reflection based on the custom angle according to Malus's Law
const angleInRadians = Utils.toRadians( photon.polarizationAngleProperty.value );
- const probabilityOfReflection = 1 - Math.pow( Math.cos( angleInRadians ), 2 );
- if ( dotRandom.nextDouble() <= probabilityOfReflection ) {
+ // Set the probability of the reflected state, the other one will change due to entanglement
+ photon.possibleStates[ 0 ].probabilityProperty.value = 1 - Math.pow( Math.cos( angleInRadians ), 2 );
- // The photon is being reflected by the beam splitter. The only direction supported currently is up.
- interaction = {
- interactionType: 'reflected',
- reflectionPoint: photonIntersectionPoint,
- reflectionDirection: UP
- };
- }
+ // The photon is being reflected by the beam splitter. The only direction supported currently is up.
+ interaction = {
+ interactionType: 'reflected',
+ reflectionPoint: photonIntersectionPoint,
+ reflectionDirection: photonState.polarization === 'vertical' ? UP : RIGHT
+ };
}
return interaction;
Index: js/photons/model/PhotonsExperimentSceneModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/PhotonsExperimentSceneModel.ts b/js/photons/model/PhotonsExperimentSceneModel.ts
--- a/js/photons/model/PhotonsExperimentSceneModel.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/PhotonsExperimentSceneModel.ts (date 1733177052960)
@@ -35,6 +35,8 @@
// time, but may have to be adjusted if other aspects of the model are changed.
const MAX_PHOTONS = 800;
+const PATH_LENGTH_UNIT = 0.2;
+
export default class PhotonsExperimentSceneModel {
// The polarizing beam splitter that the photons will encounter.
@@ -87,6 +89,18 @@
displayMode: this.laser.emissionMode === 'singlePhoton' ? 'count' : 'rate',
tandem: providedOptions.tandem.createTandem( 'horizontalPolarizationDetector' )
} );
+ this.mirror = new Mirror( new Vector2( 0.125, 0 ), {
+ tandem: providedOptions.tandem.createTandem( 'mirror' )
+ } );
+
+ // TODO: The above positioning has an unequal travel distance, which will affect the outcome. Here's a potential approach.
+ // const mirrorDistanceProportion = 0.5;
+ // const horizontalDetectorXPosition = mirrorDistanceProportion * PATH_LENGTH_UNIT;
+ // const horizontalDetectorYPosition = ( 1 - mirrorDistanceProportion ) * PATH_LENGTH_UNIT;
+ // this.horizontalPolarizationDetector = new PhotonDetector( new Vector2( horizontalDetectorXPosition, -horizontalDetectorYPosition ), 'down', {
+ // displayMode: this.laser.emissionMode === 'singlePhoton' ? 'count' : 'rate',
+ // tandem: providedOptions.tandem.createTandem( 'horizontalPolarizationDetector' )
+ // } );
// Create a derived Property for the normalized expectation value.
this.normalizedExpectationValueProperty = new DerivedProperty(
@@ -153,10 +167,6 @@
);
}
- this.mirror = new Mirror( new Vector2( 0.125, 0 ), {
- tandem: providedOptions.tandem.createTandem( 'mirror' )
- } );
-
// Create all photons that will be used in the experiment. It works better for phet-io if these are created at
// construction time and activated and deactivated as needed, rather than creating and destroying them.
_.times( MAX_PHOTONS, index => {
@@ -202,43 +212,46 @@
// Update each active photon's position based on its direction and speed and whether it interacts with any other
// model elements.
activePhotons.forEach( photon => {
-
- // Test for interactions with the potential interactors.
- let interaction: PhotonInteractionTestResult = { interactionType: 'none' };
- for ( const potentiallyInteractingElement of potentialInteractors ) {
- interaction = potentiallyInteractingElement.testForPhotonInteraction( photon, dt );
- if ( interaction.interactionType !== 'none' ) {
- break;
- }
- }
+ photon.possibleStates.forEach( photonState => {
+ if ( photonState.probabilityProperty.value > 0 ) {
+ // Test for interactions with the potential interactors.
+ let interaction: PhotonInteractionTestResult = { interactionType: 'none' };
+ for ( const potentiallyInteractingElement of potentialInteractors ) {
+ interaction = potentiallyInteractingElement.testForPhotonStateInteraction( photonState, photon, dt );
+ if ( interaction.interactionType !== 'none' ) {
+ break;
+ }
+ }
- if ( interaction.interactionType === 'reflected' ) {
+ if ( interaction.interactionType === 'reflected' ) {
- assert && assert( interaction.reflectionPoint, 'reflection point should be defined' );
- assert && assert( interaction.reflectionDirection, 'reflection direction should be defined' );
+ assert && assert( interaction.reflectionPoint, 'reflection point should be defined' );
+ assert && assert( interaction.reflectionDirection, 'reflection direction should be defined' );
- // This photon was reflected. First step it to the reflection point.
- const dtToReflection = photon.positionProperty.value.distance( interaction.reflectionPoint! ) / PHOTON_SPEED;
- assert && assert( dtToReflection <= dt );
- photon.step( dtToReflection );
+ // This photon was reflected. First step it to the reflection point.
+ const dtToReflection = photonState.positionProperty.value.distance( interaction.reflectionPoint! ) / PHOTON_SPEED;
+ assert && assert( dtToReflection <= dt );
+ photonState.step( dtToReflection );
- // Change the direction of the photon to the reflection direction.
- photon.directionProperty.set( interaction.reflectionDirection! );
+ // Change the direction of the photon to the reflection direction.
+ // photon.directionProperty.set( interaction.reflectionDirection! );
+ photonState.directionProperty.set( interaction.reflectionDirection! );
- // Step the photon the remaining time.
- photon.step( dt - dtToReflection );
- }
- else if ( interaction.interactionType === 'absorbed' ) {
-
- // The photon was absorbed, so deactivate it.
- photon.activeProperty.set( false );
- photon.positionProperty.set( Vector2.ZERO );
- }
- else {
-
- // Just step the photon normally, which will move it forward in its current travel direction.
- photon.step( dt );
- }
+ // Step the photon the remaining time.
+ photonState.step( dt - dtToReflection );
+ }
+ else if ( interaction.interactionType === 'absorbed' ) {
+ // The photon was absorbed, so deactivate it.
+ photon.activeProperty.set( false );
+ photon.possibleStates.forEach( state => state.positionProperty.reset() );
+ }
+ else {
+ // Just step the photon normally, which will move it forward in its current travel direction.
+ photonState.step( dt );
+ }
+ }
+ }
+ );
} );
// Step the photon detectors.
Index: js/photons/model/PhotonDetector.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/PhotonDetector.ts b/js/photons/model/PhotonDetector.ts
--- a/js/photons/model/PhotonDetector.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/PhotonDetector.ts (date 1733175462933)
@@ -8,6 +8,7 @@
*/
import NumberProperty from '../../../../axon/js/NumberProperty.js';
+import dotRandom from '../../../../dot/js/dotRandom.js';
import Range from '../../../../dot/js/Range.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import { Line } from '../../../../kite/js/imports.js';
@@ -17,7 +18,7 @@
import AveragingCounterNumberProperty from '../../common/model/AveragingCounterNumberProperty.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import { PHOTON_BEAM_WIDTH } from './Laser.js';
-import Photon from './Photon.js';
+import Photon, { PhotonState } from './Photon.js';
import { PhotonInteractionTestResult } from './PhotonsModel.js';
import { TPhotonInteraction } from './TPhotonInteraction.js';
@@ -87,27 +88,38 @@
} );
}
- public testForPhotonInteraction( photon: Photon, dt: number ): PhotonInteractionTestResult {
+ public testForPhotonStateInteraction( photonState: PhotonState, photon: Photon, dt: number ): PhotonInteractionTestResult {
assert && assert( photon.activeProperty.value, 'save CPU cycles - don\'t use this method with inactive photons' );
// Test for whether this photon would cross the detection aperture.
- const photonIntersectionPoint = photon.getTravelPathIntersectionPoint(
+ const photonIntersectionPoint = photonState.getTravelPathIntersectionPoint(
this.detectionLine.start,
this.detectionLine.end,
dt
);
- const detectionResult: PhotonInteractionTestResult = photonIntersectionPoint !== null ?
- { interactionType: 'absorbed' } :
- { interactionType: 'none' };
+ // Assume no interaction until proven otherwise.
+ let interaction: PhotonInteractionTestResult = { interactionType: 'none' };
+
+ if ( photonIntersectionPoint !== null ) {
+ // Evaluate the detection result based on the probability of the photon actually being here!
+ if ( dotRandom.nextDouble() < photonState.probabilityProperty.value ) {
+ photonState.probabilityProperty.value = 1; // the photon is detected!
+ interaction = { interactionType: 'absorbed' };
+ }
+ else {
+ photonState.probabilityProperty.value = 0; // the photon is not detected. Assign 100% to the alternate state.
+ }
- if ( detectionResult.interactionType === 'absorbed' ) {
+ }
+
+ if ( interaction.interactionType === 'absorbed' ) {
this.detectionCountProperty.value = Math.min( this.detectionCountProperty.value + 1, COUNT_RANGE.max );
this.detectionRateProperty.countEvent();
}
- return detectionResult;
+ return interaction;
}
public step( dt: number ): void {
Index: js/photons/model/Laser.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/photons/model/Laser.ts b/js/photons/model/Laser.ts
--- a/js/photons/model/Laser.ts (revision 6771ebf6ec9d27ccd3987715b7ac082c2dc6622a)
+++ b/js/photons/model/Laser.ts (date 1733177254865)
@@ -148,8 +148,13 @@
// Activate the photon and set its position, direction, and polarization angle.
photonToActivate.activeProperty.set( true );
- photonToActivate.positionProperty.set( this.position.plusXY( xOffset, yOffset ) );
- photonToActivate.directionProperty.set( this.emissionDirection );
+
+ photonToActivate.possibleStates.forEach( state => {
+ state.positionProperty.set( this.position.plusXY( xOffset, yOffset ) );
+ state.directionProperty.set( this.emissionDirection );
+ } );
+
+ photonToActivate.possibleStates[ 0 ].probabilityProperty.set( 1 );
photonToActivate.polarizationAngleProperty.set( polarizationAngle );
}
} |
Nevermind the patch. In design meeting it was said we should record this feature for the researchers, so it was pushed to main on the above commits |
…on with serialization, see #65
…remove inactive photon assertions, and introduce PhotonCollection for better management and serialization. See #65
I've now implemented a version where the split photons are portrayed as a circle that is always present and an image inside whose opacity varies based on the probability of the positional state. Here's a screenshot: I'd say the initial implementation of this feature is now complete, so I'll assign to the designer for feedback. |
As of this writing, the photons shown in the "Photons" screen decide where they are going when they reach the polarizing beam splitter.
For reference, this behavior is captured in the most recent dev version. Below is a screenshot where a photon has bounced off the beam splitter and is heading towards the vertical polarization detector. Note that there is not any representation of a photon headed towards the horizontal detector.
In a recent review meeting with some instructors who teach quantum physics, the instructors were bothered by this behavior because it depicts the decision being made at the beam splitter rather than at the detectors, which isn't really accurate. In today's design meeting, we decided to tackle this by showing the photons traveling both paths with an opacity value that corresponds to the likelihood of following a given path.
The text was updated successfully, but these errors were encountered: