diff --git a/src/components/AppMenuObjectDetails.vue b/src/components/AppMenuObjectDetails.vue index 49ea5d5..2236d8c 100644 --- a/src/components/AppMenuObjectDetails.vue +++ b/src/components/AppMenuObjectDetails.vue @@ -71,7 +71,7 @@ const { distance, massRatio, sizeRatio, relativePosition, relativeVelocity, escapeVelocity, gravBound, eccentricityVector, semiMajorAxis, - orbitalPeriod, + orbitalPeriod, directionalRelativePosition, directionalRelativeVelocity, } = useObjectCompareStats(focusedObject, compareObject, objects) const graphComponents = [ @@ -87,6 +87,8 @@ useTemplateRef("distance-ref"), useTemplateRef("relative-position-ref"), useTemplateRef("relative-velocity-ref"), + useTemplateRef("directional-relative-position-ref"), + useTemplateRef("directional-relative-velocity-ref"), useTemplateRef("escape-velocity-ref"), useTemplateRef("eccentricity-ref"), useTemplateRef("semi-major-axis-ref"), @@ -190,6 +192,15 @@ ref="relative-velocity-ref" :units="VELOCITY_UNITS" show-length has-graph>Relative velocity + + Direct. rel. pos. + + Direct. rel. vel. + Rel. escape velocity diff --git a/src/composables/useObjectCompareStats.ts b/src/composables/useObjectCompareStats.ts index 68b3305..47e2ff1 100644 --- a/src/composables/useObjectCompareStats.ts +++ b/src/composables/useObjectCompareStats.ts @@ -4,6 +4,9 @@ import type { StyledGravityObject } from "@/util/sim/object"; import { computed, toValue, type ComputedRef } from "vue"; import Vector3 from "@/util/linalg/Vector3"; import { DISTANCE_SMOOTHING, GRAV_CONSTANT } from "@/util/sim/constants"; +import { forceOnObject } from "@/util/sim/odeConvert"; +import Matrix from "@/util/linalg/Matrix"; +import Vector from "@/util/linalg/Vector"; /** Return value of the object compare stats composable */ export type ObjectCompareStatsReturn = { @@ -17,6 +20,16 @@ export type ObjectCompareStatsReturn = { relativePosition: ComputedRef /** Relative velocity to compare object */ relativeVelocity: ComputedRef + /** + * Directional position relative to compare object (directions are given by + * velocity and acting force of compare object) + */ + directionalRelativePosition: ComputedRef + /** + * Directional velocity relative to compare object (directions are given by + * velocity and acting force of compare object) + */ + directionalRelativeVelocity: ComputedRef /** Relative escape velocity between the two objects */ escapeVelocity: ComputedRef /** @@ -82,6 +95,45 @@ StyledGravityObject[] | null | undefined>): ObjectCompareStatsReturn { object.position.subtract(otherObject.position)) const relativeVelocity = definedComputed((object, otherObject) => object.velocity.subtract(otherObject.velocity)) + + const force = definedComputed((_, otherObject, allObjects) => + forceOnObject(otherObject, allObjects)) + const directionalBasis = definedComputed((_, otherObject) => { + if (!force.value) + return undefined + const velocity = new Vector(otherObject.velocity.x, + otherObject.velocity.y, otherObject.velocity.z) + const forceVector = new Vector(force.value.x, force.value.y, + force.value.z) + const onb = Vector.orthonormalBasis(velocity, forceVector, + new Vector(1, 0, 0), new Vector(0, 1, 0), new Vector(0, 0, 1)) + if (onb.length != 3) + return undefined + return onb as [Vector, Vector, Vector] + }) + const directionalMatrix = computed(() => { + const basis = directionalBasis.value + if (!basis) + return undefined + return new Matrix(...basis).transpose().inverse() + }) + const directionalRelativePosition = computed(() => { + if (!relativePosition.value || !directionalMatrix.value) + return undefined + const v = directionalMatrix.value.multiply(new Vector( + relativePosition.value.x, relativePosition.value.y, + relativePosition.value.z)) + return new Vector3(v.get(0), v.get(1), v.get(2)) + }) + const directionalRelativeVelocity = computed(() => { + if (!relativeVelocity.value || !directionalMatrix.value) + return undefined + const v = directionalMatrix.value.multiply(new Vector( + relativeVelocity.value.x, relativeVelocity.value.y, + relativeVelocity.value.z)) + return new Vector3(v.get(0), v.get(1), v.get(2)) + }) + const distance = definedComputed((object, otherObject) => object.position.subtract(otherObject.position).length()) const massRatio = definedComputed((object, otherObject) => @@ -142,7 +194,8 @@ StyledGravityObject[] | null | undefined>): ObjectCompareStatsReturn { return { relativePosition, relativeVelocity, distance, massRatio, sizeRatio, escapeVelocity, gravBound, barycenter, eccentricityVector, - semiMajorAxis, orbitalPeriod, + semiMajorAxis, orbitalPeriod, directionalRelativePosition, + directionalRelativeVelocity, } } \ No newline at end of file