Skip to content

Commit

Permalink
add translatable strings, match UI better in phet-io, see #63
Browse files Browse the repository at this point in the history
  • Loading branch information
jbphet committed Dec 13, 2024
1 parent e90d55e commit 950b49e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 34 deletions.
2 changes: 2 additions & 0 deletions js/QuantumMeasurementStrings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ type StringsType = {
'polarizingBeamSplitterStringProperty': LocalizedStringProperty;
'propagationStringProperty': LocalizedStringProperty;
'propagationIntoPageStringProperty': LocalizedStringProperty;
'classicalStringProperty': LocalizedStringProperty;
'classicalCoinStringProperty': LocalizedStringProperty;
'PStringProperty': LocalizedStringProperty;
'photonSourceStringProperty': LocalizedStringProperty;
'preparedStateStringProperty': LocalizedStringProperty;
'probabilityStringProperty': LocalizedStringProperty;
'probabilityOfValuePatternStringProperty': LocalizedStringProperty;
'numberOfCoinsPatternStringProperty': LocalizedStringProperty;
'quantumStringProperty': LocalizedStringProperty;
'quantumCoinQuotedStringProperty': LocalizedStringProperty;
'reprepareStringProperty': LocalizedStringProperty;
'reprepareAndRevealStringProperty': LocalizedStringProperty;
Expand Down
20 changes: 13 additions & 7 deletions js/photons/model/PhotonsExperimentSceneModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import Multilink from '../../../../axon/js/Multilink.js';
import Property from '../../../../axon/js/Property.js';
import TProperty from '../../../../axon/js/TProperty.js';
import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js';
import dotRandom from '../../../../dot/js/dotRandom.js';
import Vector2 from '../../../../dot/js/Vector2.js';
Expand All @@ -18,6 +20,8 @@ import isSettingPhetioStateProperty from '../../../../tandem/js/isSettingPhetioS
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import NullableIO from '../../../../tandem/js/types/NullableIO.js';
import NumberIO from '../../../../tandem/js/types/NumberIO.js';
import StringUnionIO from '../../../../tandem/js/types/StringUnionIO.js';
import { SystemType, SystemTypeValues } from '../../common/model/SystemType.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import Laser, { PhotonEmissionMode } from './Laser.js';
import Mirror from './Mirror.js';
Expand Down Expand Up @@ -64,29 +68,31 @@ export default class PhotonsExperimentSceneModel {
// Whether the simulation is currently playing, which in this case means whether the photons are moving.
public readonly isPlayingProperty: BooleanProperty;

// The Classical understanding of this experiment implied that photons would choose a path at
// the beam splitter. This is controlled by the Classical/Quantum toggle at the view.
public readonly collapsePhotonsAtBeamSplitterProperty: BooleanProperty;
// Whether the photons behave as classical or quantum particles. When they are classical, they will choose a path
// at the beam splitter. When they are quantum, they will be in a superposition of states.
public readonly particleBehaviorModeProperty: TProperty<SystemType>;

public constructor( providedOptions: PhotonsExperimentSceneModelOptions ) {

// 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.
this.photonCollection = new PhotonCollection( providedOptions.tandem.createTandem( 'photonCollection' ) );

this.collapsePhotonsAtBeamSplitterProperty = new BooleanProperty( true, {
tandem: providedOptions.tandem.createTandem( 'collapsePhotonsAtBeamSplitterProperty' )
this.particleBehaviorModeProperty = new Property( 'classical', {
tandem: providedOptions.tandem.createTandem( 'particleBehaviorModeProperty' ),
phetioValueType: StringUnionIO( SystemTypeValues ),
validValues: SystemTypeValues
} );

this.collapsePhotonsAtBeamSplitterProperty.link( () => {
this.particleBehaviorModeProperty.link( () => {
if ( !isSettingPhetioStateProperty.value ) {
this.photonCollection.clear();
}
} );

this.polarizingBeamSplitter = new PolarizingBeamSplitter( Vector2.ZERO, {
tandem: providedOptions.tandem.createTandem( 'polarizingBeamSplitter' ),
collapsePhotonsProperty: this.collapsePhotonsAtBeamSplitterProperty
particleBehaviorModeProperty: this.particleBehaviorModeProperty
} );

// Create the laser that will emit the photons that will be sent toward the polarizing beam splitter.
Expand Down
14 changes: 8 additions & 6 deletions js/photons/model/PolarizingBeamSplitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ import Vector2 from '../../../../dot/js/Vector2.js';
import { Line } from '../../../../kite/js/imports.js';
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';
import { SystemType } from '../../common/model/SystemType.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import Photon, { RIGHT, UP } from './Photon.js';
import { PhotonMotionState } from './PhotonMotionState.js';
import { PhotonInteractionTestResult } from './PhotonsModel.js';
import { TPhotonInteraction } from './TPhotonInteraction.js';

type SelfOptions = {
collapsePhotonsProperty: TReadOnlyProperty<boolean>;
particleBehaviorModeProperty: TReadOnlyProperty<SystemType>;
};
type PolarizingBeamSplitterOptions = SelfOptions & PickRequired<PhetioObjectOptions, 'tandem'>;

export default class PolarizingBeamSplitter implements TPhotonInteraction {
class PolarizingBeamSplitter implements TPhotonInteraction {

// The position of the center of the beam splitter in two-dimensional space. Units are in meters.
public readonly centerPosition: Vector2;
Expand All @@ -38,11 +39,11 @@ export default class PolarizingBeamSplitter implements TPhotonInteraction {
public readonly polarizingSurfaceLine: Line;

// A flag that indicates whether to collapse the interacting photons, which represents the classical case.
public readonly collapsePhotonsProperty: TReadOnlyProperty<boolean>;
public readonly particleBehaviorModeProperty: TReadOnlyProperty<SystemType>;

public constructor( centerPosition: Vector2, providedOptions: PolarizingBeamSplitterOptions ) {
this.centerPosition = centerPosition;
this.collapsePhotonsProperty = providedOptions.collapsePhotonsProperty;
this.particleBehaviorModeProperty = providedOptions.particleBehaviorModeProperty;

// Initialize the line that represents the position of the beam splitter in the model.
const endpoint1 = new Vector2( centerPosition.x - this.size.width / 2, centerPosition.y - this.size.height / 2 );
Expand Down Expand Up @@ -73,7 +74,7 @@ export default class PolarizingBeamSplitter implements TPhotonInteraction {
const angleInRadians = Utils.toRadians( photon.polarizationAngle );
const probabilityOfReflection = 1 - Math.pow( Math.cos( angleInRadians ), 2 );

if ( this.collapsePhotonsProperty.value ) {
if ( this.particleBehaviorModeProperty.value === 'classical' ) {

// This is the classical case, where photons "choose" a path at the beam splitter.
if ( dotRandom.nextDouble() <= probabilityOfReflection ) {
Expand Down Expand Up @@ -116,4 +117,5 @@ export default class PolarizingBeamSplitter implements TPhotonInteraction {
}
}

quantumMeasurement.register( 'PolarizingBeamSplitter', PolarizingBeamSplitter );
quantumMeasurement.register( 'PolarizingBeamSplitter', PolarizingBeamSplitter );
export default PolarizingBeamSplitter;
59 changes: 38 additions & 21 deletions js/photons/view/PhotonTestingArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@
* @author John Blanco, PhET Interactive Simulations
*/

import PhetioProperty from '../../../../axon/js/PhetioProperty.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
import WithRequired from '../../../../phet-core/js/types/WithRequired.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import { Node, NodeOptions, Text } from '../../../../scenery/js/imports.js';
import AquaRadioButtonGroup from '../../../../sun/js/AquaRadioButtonGroup.js';
import { SystemType, SystemTypeValues } from '../../common/model/SystemType.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import QuantumMeasurementStrings from '../../QuantumMeasurementStrings.js';
import PhotonsExperimentSceneModel from '../model/PhotonsExperimentSceneModel.js';
import LaserNode from './LaserNode.js';
import MirrorNode from './MirrorNode.js';
Expand All @@ -25,7 +28,7 @@ import PolarizingBeamSplitterNode from './PolarizingBeamSplitterNode.js';
type SelfOptions = EmptySelfOptions;
type PhotonTestingAreaOptions = SelfOptions & WithRequired<NodeOptions, 'tandem'>;

export default class PhotonTestingArea extends Node {
class PhotonTestingArea extends Node {

private readonly photonSprites: PhotonSprites;

Expand All @@ -45,24 +48,37 @@ export default class PhotonTestingArea extends Node {
} );

// TODO: This might live here temporarily mainly for a demo. If the feature stays, consider moving elsewhere https://github.com/phetsims/quantum-measurement/issues/63
const visualizationModeRadioButtonGroupTandem = providedOptions.tandem.createTandem( 'visualizationModeRadioButtonGroup' );
const visualizationModeRadioButtonGroup = new AquaRadioButtonGroup( model.collapsePhotonsAtBeamSplitterProperty, [ true, false ].map( classical => {
const name = classical ? 'Classical' : 'Quantum';
return {
value: classical,
createNode: () => new Text(
name,
{ font: new PhetFont( 15 ) } ),
tandemName: `${name.toLowerCase()}RadioButton`,
phetioVisiblePropertyInstrumented: false
};
} ), {
spacing: 10,
left: laserNode.left,
bottom: laserNode.top - 20,
tandem: visualizationModeRadioButtonGroupTandem,
phetioFeatured: true
} );
const particleBehaviorModeRadioButtonGroupTandem = providedOptions.tandem.createTandem( 'particleBehaviorModeRadioButtonGroup' );
const particleBehaviorModeRadioButtonGroup = new AquaRadioButtonGroup<SystemType>(
model.particleBehaviorModeProperty as PhetioProperty<SystemType>,
SystemTypeValues.map( behaviorMode => {

const nameProperty = behaviorMode === 'classical' ?
QuantumMeasurementStrings.classicalStringProperty :
QuantumMeasurementStrings.quantumStringProperty;

const tandemRootName = behaviorMode === 'classical' ? 'classical' : 'quantum';
const tandemName = `${tandemRootName}RadioButton`;

return {
value: behaviorMode,
createNode: () => new Text(
nameProperty,
{ font: new PhetFont( 15 ) }
),
tandemName: tandemName,
phetioVisiblePropertyInstrumented: false
};
}
),
{
spacing: 10,
left: laserNode.left,
bottom: laserNode.top - 20,
tandem: particleBehaviorModeRadioButtonGroupTandem,
phetioFeatured: true
}
);

const verticalPolarizationDetector = new PhotonDetectorNode(
model.verticalPolarizationDetector,
Expand Down Expand Up @@ -93,7 +109,7 @@ export default class PhotonTestingArea extends Node {

const options = optionize<PhotonTestingAreaOptions, SelfOptions, NodeOptions>()( {
children: [
visualizationModeRadioButtonGroup,
particleBehaviorModeRadioButtonGroup,
laserNode,
polarizingBeamSplitterNode,
verticalPolarizationDetector,
Expand Down Expand Up @@ -123,4 +139,5 @@ export default class PhotonTestingArea extends Node {
}
}

quantumMeasurement.register( 'PhotonTestingArea', PhotonTestingArea );
quantumMeasurement.register( 'PhotonTestingArea', PhotonTestingArea );
export default PhotonTestingArea;
6 changes: 6 additions & 0 deletions quantum-measurement-strings_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@
"propagationIntoPage": {
"value": "Propagation (into page)"
},
"classical": {
"value": "Classical"
},
"classicalCoin": {
"value": "Classical Coin"
},
Expand All @@ -125,6 +128,9 @@
"numberOfCoinsPattern": {
"value": "N = {{number}}"
},
"quantum": {
"value": "Quantum"
},
"quantumCoinQuoted": {
"value": "Quantum \"Coin\""
},
Expand Down

0 comments on commit 950b49e

Please sign in to comment.