From 662ff96e3cc66f5df971819427e229598c89c28a Mon Sep 17 00:00:00 2001 From: jbphet Date: Wed, 9 Oct 2024 14:28:28 -0600 Subject: [PATCH] add initial beam splitter, flesh out Photons model a bit more --- js/photons/model/PhotonDetector.ts | 2 - js/photons/model/PhotonsModel.ts | 19 +++++-- js/photons/model/PolarizingBeamSplitter.ts | 61 ++++++++++++++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 js/photons/model/PolarizingBeamSplitter.ts diff --git a/js/photons/model/PhotonDetector.ts b/js/photons/model/PhotonDetector.ts index 3e563b7d..bcf4ef2c 100644 --- a/js/photons/model/PhotonDetector.ts +++ b/js/photons/model/PhotonDetector.ts @@ -16,8 +16,6 @@ import quantumMeasurement from '../../quantumMeasurement.js'; type SelfOptions = EmptySelfOptions; type PhotonDetectorOptions = SelfOptions & PickRequired; - -// constants export type DetectionDirection = ( [ 'up', 'down' ] )[number]; export default class PhotonDetector { diff --git a/js/photons/model/PhotonsModel.ts b/js/photons/model/PhotonsModel.ts index b75bb56b..01b3fb75 100644 --- a/js/photons/model/PhotonsModel.ts +++ b/js/photons/model/PhotonsModel.ts @@ -4,14 +4,16 @@ * PhotonsModel is the primary model class for the Photons screen. It manages the general model state and behavior for * the photons that travel from the source to the detectors. * - * Part of what this model does is position photons in two-dimensional space. This space is set up to center on the + * Part of what this model does is move photons in two-dimensional space. This space is set up to center on the * polarizing beam splitter, which is at the center of the screen. The x-axis is horizontal and the y-axis is vertical. - * Units are in meters. + * Units are in meters. The photons are emitted from a source, travel to the polarizing beam splitter, and then are + * either reflected or transmitted. The photons are then detected by two photon detectors. * * @author John Blanco, PhET Interactive Simulations */ import NumberProperty from '../../../../axon/js/NumberProperty.js'; +import Range from '../../../../dot/js/Range.js'; import Vector2 from '../../../../dot/js/Vector2.js'; import TModel from '../../../../joist/js/TModel.js'; import { EmptySelfOptions } from '../../../../phet-core/js/optionize.js'; @@ -19,13 +21,17 @@ import PickRequired from '../../../../phet-core/js/types/PickRequired.js'; import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js'; import quantumMeasurement from '../../quantumMeasurement.js'; import PhotonDetector from './PhotonDetector.js'; +import PolarizingBeamSplitter from './PolarizingBeamSplitter.js'; type SelfOptions = EmptySelfOptions; type QuantumMeasurementModelOptions = SelfOptions & PickRequired; export default class PhotonsModel implements TModel { - // The angle of polarization for the polarizing beam splitter. + // The polarizing beam splitter that the photons will encounter. + public readonly polarizingBeamSplitter: PolarizingBeamSplitter; + + // The angle of polarization for the polarizing beam splitter, in degrees. Zero is horizontal and 90 is vertical. public readonly photonPolarizationAngleProperty: NumberProperty; // photon detectors @@ -34,7 +40,12 @@ export default class PhotonsModel implements TModel { public constructor( providedOptions: QuantumMeasurementModelOptions ) { - this.photonPolarizationAngleProperty = new NumberProperty( 0, { + this.polarizingBeamSplitter = new PolarizingBeamSplitter( new Vector2( 0, 0 ), { + tandem: providedOptions.tandem.createTandem( 'polarizingBeamSplitter' ) + } ); + + this.photonPolarizationAngleProperty = new NumberProperty( 45, { + range: new Range( 0, 90 ), tandem: providedOptions.tandem.createTandem( 'photonPolarizationAngleProperty' ) } ); diff --git a/js/photons/model/PolarizingBeamSplitter.ts b/js/photons/model/PolarizingBeamSplitter.ts new file mode 100644 index 00000000..c0b50282 --- /dev/null +++ b/js/photons/model/PolarizingBeamSplitter.ts @@ -0,0 +1,61 @@ +// Copyright 2024, University of Colorado Boulder + +/** + * PolarizingBeamSplitter is a model element that represents a device that splits a beam of photons into two beams based + * on the polarization of the photons. + * + * @author John Blanco, PhET Interactive Simulations + */ + +import NumberProperty from '../../../../axon/js/NumberProperty.js'; +import Property from '../../../../axon/js/Property.js'; +import Vector2 from '../../../../dot/js/Vector2.js'; +import { Line } from '../../../../kite/js/imports.js'; +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'; + +type SelfOptions = EmptySelfOptions; +type PolarizingBeamSplitterOptions = SelfOptions & PickRequired; + +export type PresetPolarizationDirections = ( [ 'vertical', 'horizontal', 'fortyFiveDegrees', 'custom' ] )[number]; + +// constants +const WIDTH = 0.1; // the width, in meters, of the beam splitter +const ROTATIONAL_ANGLE = Math.PI / 4; // the angle at which the beam splitter is rotated, in radians, zero is horizontal + +export default class PolarizingBeamSplitter { + + // The position of the center of the beam splitter in two-dimensional space. Units are in meters. + public readonly centerPosition: Vector2; + + // A line in model space that represents the position of the beam splitter. + public readonly positionalLine: Line; + + // The direction of polarization that the beam splitter is set to. This can be one of the preset directions or a + // custom angle. + public readonly presetPolarizationDirectionProperty: Property; + + // The custom angle at which the beam splitter is set, in degrees. This is only used when the preset direction is + // "custom". + public readonly customPolarizationAngleProperty: NumberProperty; + + public constructor( centerPosition: Vector2, providedOptions: PolarizingBeamSplitterOptions ) { + this.centerPosition = centerPosition; + + // Initialize the line that represents the position of the beam splitter in the model. + const endpoint1 = centerPosition.plusXY( WIDTH / 2, 0 ).rotated( ROTATIONAL_ANGLE ); + const endpoint2 = centerPosition.plusXY( -WIDTH / 2, 0 ).rotated( ROTATIONAL_ANGLE ); + this.positionalLine = new Line( endpoint1, endpoint2 ); + + this.presetPolarizationDirectionProperty = new Property( 'fortyFiveDegrees', { + tandem: providedOptions.tandem.createTandem( 'presetPolarizationDirectionProperty' ) + } ); + this.customPolarizationAngleProperty = new NumberProperty( 45, { + tandem: providedOptions.tandem.createTandem( 'customPolarizationAngleProperty' ) + } ); + } +} + +quantumMeasurement.register( 'PolarizingBeamSplitter', PolarizingBeamSplitter ); \ No newline at end of file