Path: blob/main/frontend/vue/components/AmplitudeDisk/AmplitudeAdditionDisk.vue
3376 views
<template> <div class="amplitude-addition-disk" > <AmplitudeDisk class="amplitude-addition-disk__result" :magnitude="amplitudeResult.magnitude" :phase="amplitudeResult.phase" /> <div class="amplitude-addition-disk__summands-arrows"> <AmplitudeArrow class="amplitude-addition-disk__summands-arrows__A" :amplitude="amplitudeA" :is-interactive="false" @updateAmplitude="updateInternalAmplitude" /> <div class="amplitude-addition-disk__summands-arrows__B__wrapper" :style="`--phase-offset: ${phaseA}; --magnitude-offset:${magnitudeA};`" > <AmplitudeArrow class="amplitude-addition-disk__summands-arrows__B" :amplitude="amplitudeB" :is-interactive="false" @updateAmplitude="updateInternalAmplitude" /> </div> </div> </div> </template> <script lang="ts"> import { defineComponent } from 'vue-demi' import { Point, toDeg, toRad } from '@mathigon/euclid' import AmplitudeArrow from './AmplitudeArrow.vue' import AmplitudeDisk from './AmplitudeDisk.vue' import { Amplitude } from './amplitude' export default defineComponent({ name: 'AmplitudeAdditionDisk', components: { AmplitudeArrow, AmplitudeDisk }, props: { magnitudeA: { type: Number, required: false, default: 0.7071 }, phaseA: { type: Number, required: false, default: 30 }, magnitudeB: { type: Number, required: false, default: 0.7071 }, phaseB: { type: Number, required: false, default: 30 } }, computed: { amplitudeA (): Amplitude { return { phase: this.phaseA, magnitude: this.magnitudeA } }, amplitudeB (): Amplitude { return { phase: this.phaseB, magnitude: this.magnitudeB } }, amplitudeResult (): Amplitude { const vectorA = Point.fromPolar(toRad(this.phaseA), this.magnitudeA) const vectorB = Point.fromPolar(toRad(this.phaseB), this.magnitudeB) const vectorResult = vectorA.add(vectorB) const vectorResultUnit = vectorResult.unitVector const phaseResult = toDeg(Math.atan2(vectorResultUnit.y, vectorResultUnit.x)) const magnitudeResult = vectorResult.length return { phase: phaseResult, magnitude: magnitudeResult } }, amplitudeOverflow (): boolean { return this.amplitudeResult.magnitude > 1 } } }) </script> <style lang="scss" scoped> @import 'carbon-components/scss/globals/scss/typography'; @import '~/../scss/variables/colors.scss'; .amplitude-addition-disk { position: relative; width: 100px; height: 100px; margin: $spacing-05; &__result { position: relative; top: 0; left: 0; margin: 0; } &__summands-arrows { position: absolute; top: 0; left: 0; width: 100%; height: 100%; &__A { position: absolute; left: 50%; top: 50%; opacity: 0.5; } &__B { position: absolute; left: 50%; top: 50%; opacity: 0.5; &__wrapper { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; transform: rotate(calc(var(--phase-offset, 30) * -1deg)) translate(calc(var(--magnitude-offset, 1) * 50%), 0) rotate(calc(var(--phase-offset, 30) * 1deg)); } } } } </style>