From 3fb4a8649f9645315d35ba86f2e450aae53d1bf9 Mon Sep 17 00:00:00 2001 From: Seggan Date: Fri, 23 Feb 2024 16:42:45 -0500 Subject: [PATCH] Yay velocity vectors work --- .../galactifun/{util => }/Constants.kt | 4 +- .../galactifun/api/objects/CelestialObject.kt | 2 +- .../galactifun/api/objects/PlanetaryObject.kt | 2 +- .../galactifun/api/objects/Star.kt | 4 +- .../api/objects/properties/Orbit.kt | 46 +++++++------ .../galactifun/base/BaseUniverse.kt | 4 +- .../galactifun/core/managers/PlanetManager.kt | 2 +- .../serial/CollectionBlockStorageDataType.kt | 2 +- .../serial/MiscBlockStorageDataType.kt | 2 +- .../addoncommunity/galactifun/units/Angle.kt | 3 + .../galactifun/units/Distance.kt | 9 +-- .../galactifun/units/SphericalPosition.kt | 27 -------- .../units/coordiantes/CartesianVector.kt | 44 +++++++++++++ .../units/coordiantes/PolarVector.kt | 31 +++++++++ .../units/coordiantes/SphericalVector.kt | 27 ++++++++ .../test/api/objects/properties/OrbitTest.kt | 65 +++++++++++++++---- 16 files changed, 195 insertions(+), 79 deletions(-) rename src/main/kotlin/io/github/addoncommunity/galactifun/{util => }/Constants.kt (84%) delete mode 100644 src/main/kotlin/io/github/addoncommunity/galactifun/units/SphericalPosition.kt create mode 100644 src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/CartesianVector.kt create mode 100644 src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/PolarVector.kt create mode 100644 src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/SphericalVector.kt diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/util/Constants.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/Constants.kt similarity index 84% rename from src/main/kotlin/io/github/addoncommunity/galactifun/util/Constants.kt rename to src/main/kotlin/io/github/addoncommunity/galactifun/Constants.kt index 553c2db..44f2a62 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/util/Constants.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/Constants.kt @@ -1,4 +1,4 @@ -package io.github.addoncommunity.galactifun.util +package io.github.addoncommunity.galactifun import org.bukkit.Location import org.bukkit.World @@ -7,7 +7,7 @@ object Constants { const val KM_PER_LY = 9.461e12 const val KM_PER_PC = 3.086e13 - const val KM_PER_AU = 1.496e8 + const val KM_PER_AU = 1.495978707e8 const val GRAVITATIONAL_CONSTANT = 6.674e-11 const val EARTH_GRAVITY = 9.81 diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/CelestialObject.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/CelestialObject.kt index e61cf18..91394dd 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/CelestialObject.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/CelestialObject.kt @@ -1,10 +1,10 @@ package io.github.addoncommunity.galactifun.api.objects +import io.github.addoncommunity.galactifun.Constants import io.github.addoncommunity.galactifun.api.objects.properties.Orbit import io.github.addoncommunity.galactifun.units.Angle.Companion.degrees import io.github.addoncommunity.galactifun.units.Distance import io.github.addoncommunity.galactifun.units.Mass -import io.github.addoncommunity.galactifun.util.Constants import io.github.addoncommunity.galactifun.util.LazyDouble import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack import io.github.thebusybiscuit.slimefun4.utils.ChatUtils diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/PlanetaryObject.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/PlanetaryObject.kt index 50cd8d7..2e9fafc 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/PlanetaryObject.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/PlanetaryObject.kt @@ -1,5 +1,6 @@ package io.github.addoncommunity.galactifun.api.objects +import io.github.addoncommunity.galactifun.Constants import io.github.addoncommunity.galactifun.api.objects.properties.DayCycle import io.github.addoncommunity.galactifun.api.objects.properties.Orbit import io.github.addoncommunity.galactifun.api.objects.properties.OrbitPosition @@ -9,7 +10,6 @@ import io.github.addoncommunity.galactifun.core.managers.PlanetManager import io.github.addoncommunity.galactifun.units.Distance import io.github.addoncommunity.galactifun.units.Distance.Companion.meters import io.github.addoncommunity.galactifun.units.cos -import io.github.addoncommunity.galactifun.util.Constants import io.github.seggan.kfun.location.plus import kotlinx.datetime.Instant import org.bukkit.Location diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/Star.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/Star.kt index 0a066be..9d42fba 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/Star.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/Star.kt @@ -3,7 +3,7 @@ package io.github.addoncommunity.galactifun.api.objects import io.github.addoncommunity.galactifun.units.Distance import io.github.addoncommunity.galactifun.units.Distance.Companion.meters import io.github.addoncommunity.galactifun.units.Mass -import io.github.addoncommunity.galactifun.units.SphericalPosition +import io.github.addoncommunity.galactifun.units.coordiantes.SphericalVector import kotlinx.datetime.Instant import org.bukkit.Material import org.bukkit.inventory.ItemStack @@ -12,7 +12,7 @@ class Star( name: String, override val mass: Mass, override val radius: Distance, - val position: SphericalPosition + val position: SphericalVector ) : CelestialObject(name, ItemStack(Material.SUNFLOWER)) { override fun distanceTo(other: CelestialObject, time: Instant): Distance { diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/properties/Orbit.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/properties/Orbit.kt index 40b6a06..0491544 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/properties/Orbit.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/api/objects/properties/Orbit.kt @@ -4,12 +4,15 @@ import io.github.addoncommunity.galactifun.api.objects.CelestialObject import io.github.addoncommunity.galactifun.units.* import io.github.addoncommunity.galactifun.units.Angle.Companion.radians import io.github.addoncommunity.galactifun.units.Distance.Companion.meters +import io.github.addoncommunity.galactifun.units.coordiantes.CartesianVector +import io.github.addoncommunity.galactifun.units.coordiantes.PolarVector import io.github.addoncommunity.galactifun.util.LazyDouble import kotlinx.datetime.Instant -import org.joml.Vector2d import java.util.* -import kotlin.math.acos +import kotlin.math.atan2 import kotlin.math.sqrt +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds data class Orbit( val parent: CelestialObject, @@ -26,6 +29,11 @@ data class Orbit( require(eccentricity < 1) { "Eccentricity must be less than 1" } } + val period: Duration by lazy { + val a = semimajorAxis.meters + (2 * Math.PI * sqrt(a * a * a / parent.gravitationalParameter)).seconds + } + val meanMotion by LazyDouble { val a = semimajorAxis.meters sqrt(parent.gravitationalParameter / (a * a * a)) @@ -42,9 +50,11 @@ data class Orbit( return eccentricAnomalyCache.getOrPut(time) { kelpersEquation(meanAnomaly(time), eccentricity) } } + private val beta by LazyDouble { eccentricity / (1 + sqrt(1 - eccentricity * eccentricity)) } + fun trueAnomaly(time: Instant): Angle { - val cosE = cos(eccentricAnomaly(time)) - return acos((cosE - eccentricity) / (1 - eccentricity * cosE)).radians + val e = eccentricAnomaly(time) + return atan2(beta * sin(e), 1 - beta * cos(e)).radians * 2.0 + e } fun radius(time: Instant): Distance { @@ -53,24 +63,18 @@ data class Orbit( return (a * (1 - eccentricity * cos(e))).meters } - val sinOmega by LazyDouble { sin(argumentOfPeriapsis) } - val cosOmega by LazyDouble { cos(argumentOfPeriapsis) } - - fun velocityVectorAt(time: Instant): Vector2d { - val p = semimajorAxis.meters * (1 - eccentricity * eccentricity) - val h = sqrt(parent.gravitationalParameter * p) - val r = radius(time).meters - val nu = trueAnomaly(time) - val sinOmegaNu = sin(argumentOfPeriapsis + nu) - val cosOmegaNu = cos(argumentOfPeriapsis + nu) + fun position(time: Instant): PolarVector = PolarVector(radius(time), trueAnomaly(time)) - val x = r * (cosOmega * cosOmegaNu - sinOmega * sinOmegaNu) - val y = r * (sinOmega * cosOmegaNu + cosOmega * sinOmegaNu) + private val deltaTimeForVelocity: Duration by lazy { period / 1e6 } - val magic = (h * eccentricity) / (r * p) * sin(nu) - val vx = x * magic - h / r * (cosOmega * sinOmegaNu + sinOmega * cosOmegaNu) - val vy = y * magic - h / r * (sinOmega * sinOmegaNu - cosOmega * cosOmegaNu) - return Vector2d(vx, vy) + fun velocity(time: Instant): CartesianVector { + // Do a tiny bit of calculus to find the velocity vector + val deltaTime = time + deltaTimeForVelocity + val pos1 = position(time) + val pos2 = position(deltaTime) + val w = eccentricAnomaly(time).degrees to eccentricAnomaly(deltaTime).degrees + val z = trueAnomaly(time).degrees to trueAnomaly(deltaTime).degrees + return (pos2.cartesian - pos1.cartesian) / deltaTimeForVelocity.doubleSeconds } companion object { @@ -78,7 +82,7 @@ data class Orbit( * How much faster time is concerning orbital mechanics than in real life. * Minecraft is 72 times faster than real life, and a year is 12 times shorter than in real life. */ - const val TIME_SCALE = 72.0 * 12.0 + var TIME_SCALE = 72.0 * 12.0 /** * A tiny eccentricity to use for otherwise circular orbits in order to avoid maths problems. diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/base/BaseUniverse.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/base/BaseUniverse.kt index 2d95ea3..05e3159 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/base/BaseUniverse.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/base/BaseUniverse.kt @@ -7,7 +7,7 @@ import io.github.addoncommunity.galactifun.units.Angle.Companion.radians import io.github.addoncommunity.galactifun.units.Distance.Companion.kilometers import io.github.addoncommunity.galactifun.units.Distance.Companion.meters import io.github.addoncommunity.galactifun.units.Mass.Companion.kilograms -import io.github.addoncommunity.galactifun.units.SphericalPosition +import io.github.addoncommunity.galactifun.units.coordiantes.SphericalVector object BaseUniverse { @@ -16,7 +16,7 @@ object BaseUniverse { mass = 1.989e30.kilograms, radius = 695700.0.kilometers, // The sun is at the center of the universe, yay! - position = SphericalPosition(0.0.radians, 0.0.radians, 0.0.meters) + position = SphericalVector(0.0.radians, 0.0.radians, 0.0.meters) ) val earth = Earth() diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/core/managers/PlanetManager.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/core/managers/PlanetManager.kt index 321f7c1..b99a437 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/core/managers/PlanetManager.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/core/managers/PlanetManager.kt @@ -1,6 +1,7 @@ package io.github.addoncommunity.galactifun.core.managers import com.jeff_media.morepersistentdatatypes.DataType +import io.github.addoncommunity.galactifun.Constants import io.github.addoncommunity.galactifun.api.objects.PlanetaryObject import io.github.addoncommunity.galactifun.api.objects.planet.PlanetaryWorld import io.github.addoncommunity.galactifun.api.objects.properties.DayCycle @@ -11,7 +12,6 @@ import io.github.addoncommunity.galactifun.core.space.SpaceGenerator import io.github.addoncommunity.galactifun.pluginInstance import io.github.addoncommunity.galactifun.runOnNextTick import io.github.addoncommunity.galactifun.test.MarkerMock -import io.github.addoncommunity.galactifun.util.Constants import io.github.addoncommunity.galactifun.util.getNearbyEntitiesByType import io.github.addoncommunity.galactifun.util.key import io.github.addoncommunity.galactifun.util.spawn diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/serial/CollectionBlockStorageDataType.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/serial/CollectionBlockStorageDataType.kt index 61147f4..84a47de 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/serial/CollectionBlockStorageDataType.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/serial/CollectionBlockStorageDataType.kt @@ -1,6 +1,6 @@ package io.github.addoncommunity.galactifun.serial -import io.github.addoncommunity.galactifun.util.Constants +import io.github.addoncommunity.galactifun.Constants import io.github.seggan.kfun.serial.BlockStorageDataType abstract class CollectionBlockStorageDataType>( diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/serial/MiscBlockStorageDataType.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/serial/MiscBlockStorageDataType.kt index b29ea2d..09972ed 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/serial/MiscBlockStorageDataType.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/serial/MiscBlockStorageDataType.kt @@ -1,6 +1,6 @@ package io.github.addoncommunity.galactifun.serial -import io.github.addoncommunity.galactifun.util.Constants +import io.github.addoncommunity.galactifun.Constants import io.github.seggan.kfun.serial.BlockStorageDataType import kotlin.reflect.KClass diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/Angle.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/Angle.kt index 785cb9a..e6b653f 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/units/Angle.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/units/Angle.kt @@ -17,6 +17,9 @@ value class Angle private constructor(val radians: Double) : Comparable { val milliarcseconds: Double get() = arcseconds * 1000 + val standardForm: Angle + get() = Angle((radians % (2 * PI) + 2 * PI) % (2 * PI)) + companion object { const val DEGREES_PER_RADIAN = 180 / Math.PI diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/Distance.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/Distance.kt index 0583efc..55776f9 100644 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/units/Distance.kt +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/units/Distance.kt @@ -1,7 +1,6 @@ package io.github.addoncommunity.galactifun.units -import io.github.addoncommunity.galactifun.util.Constants -import kotlin.math.abs +import io.github.addoncommunity.galactifun.Constants @JvmInline value class Distance private constructor(val meters: Double) : Comparable { @@ -30,12 +29,8 @@ value class Distance private constructor(val meters: Double) : Comparable= 0) { "Distance must be positive" } - } - operator fun plus(other: Distance): Distance = Distance(meters + other.meters) - operator fun minus(other: Distance): Distance = Distance(abs(meters - other.meters)) + operator fun minus(other: Distance): Distance = Distance(meters - other.meters) operator fun times(scalar: Double): Distance = Distance(meters * scalar) operator fun div(scalar: Double): Distance = Distance(meters / scalar) operator fun rem(scalar: Double): Distance = Distance(meters % scalar) diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/SphericalPosition.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/SphericalPosition.kt deleted file mode 100644 index c401743..0000000 --- a/src/main/kotlin/io/github/addoncommunity/galactifun/units/SphericalPosition.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.addoncommunity.galactifun.units - -import io.github.addoncommunity.galactifun.units.Distance.Companion.meters -import kotlin.math.sqrt - -data class SphericalPosition( - val rightAscension: Angle, - val declination: Angle, - val distance: Distance -) { - - // What? I'm not afraid of a few trigonometric functions and a square root or two - fun distanceTo(other: SphericalPosition): Distance { - val x = distance * sin(declination) * cos(rightAscension) - val y = distance * sin(declination) * sin(rightAscension) - val z = distance * cos(declination) - - val x2 = other.distance * sin(other.declination) * cos(other.rightAscension) - val y2 = other.distance * sin(other.declination) * sin(other.rightAscension) - val z2 = other.distance * cos(other.declination) - - val term1 = (x - x2).meters - val term2 = (y - y2).meters - val term3 = (z - z2).meters - return sqrt(term1 * term1 + term2 * term2 + term3 * term3).meters - } -} \ No newline at end of file diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/CartesianVector.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/CartesianVector.kt new file mode 100644 index 0000000..1b4d6f3 --- /dev/null +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/CartesianVector.kt @@ -0,0 +1,44 @@ +package io.github.addoncommunity.galactifun.units.coordiantes + +import io.github.addoncommunity.galactifun.units.Angle.Companion.radians +import io.github.addoncommunity.galactifun.units.Distance +import io.github.addoncommunity.galactifun.units.Distance.Companion.meters +import kotlin.math.atan2 +import kotlin.math.sqrt + +data class CartesianVector( + val x: Distance, + val y: Distance +) { + + val polar by lazy { + val theta = atan2(y.meters, x.meters).radians + PolarVector(length, theta) + } + + val length by lazy { + sqrt(x.meters * x.meters + y.meters * y.meters).meters + } + + operator fun plus(other: CartesianVector): CartesianVector { + return CartesianVector(x + other.x, y + other.y) + } + + operator fun minus(other: CartesianVector): CartesianVector { + return CartesianVector(x - other.x, y - other.y) + } + + operator fun times(scalar: Double): CartesianVector { + return CartesianVector(x * scalar, y * scalar) + } + + operator fun div(scalar: Double): CartesianVector { + return CartesianVector(x / scalar, y / scalar) + } + + fun distanceTo(other: CartesianVector): Distance { + val term1 = (x - other.x).meters + val term2 = (y - other.y).meters + return sqrt(term1 * term1 + term2 * term2).meters + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/PolarVector.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/PolarVector.kt new file mode 100644 index 0000000..b3f27a6 --- /dev/null +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/PolarVector.kt @@ -0,0 +1,31 @@ +package io.github.addoncommunity.galactifun.units.coordiantes + +import io.github.addoncommunity.galactifun.units.Angle +import io.github.addoncommunity.galactifun.units.Distance +import io.github.addoncommunity.galactifun.units.cos +import io.github.addoncommunity.galactifun.units.sin + +data class PolarVector( + val radius: Distance, + val angle: Angle +) { + + val cartesian: CartesianVector by lazy { + CartesianVector( + x = radius * cos(angle), + y = radius * sin(angle) + ) + } + + operator fun times(scalar: Double): PolarVector { + return PolarVector(radius * scalar, angle * scalar) + } + + operator fun div(scalar: Double): PolarVector { + return PolarVector(radius / scalar, angle / scalar) + } + + fun distanceTo(other: PolarVector): Distance { + return cartesian.distanceTo(other.cartesian) + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/SphericalVector.kt b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/SphericalVector.kt new file mode 100644 index 0000000..892cdee --- /dev/null +++ b/src/main/kotlin/io/github/addoncommunity/galactifun/units/coordiantes/SphericalVector.kt @@ -0,0 +1,27 @@ +package io.github.addoncommunity.galactifun.units.coordiantes + +import io.github.addoncommunity.galactifun.units.Angle +import io.github.addoncommunity.galactifun.units.Distance +import io.github.addoncommunity.galactifun.units.Distance.Companion.meters +import io.github.addoncommunity.galactifun.units.cos +import io.github.addoncommunity.galactifun.units.sin +import org.joml.Vector3d + +data class SphericalVector( + val rightAscension: Angle, + val declination: Angle, + val distance: Distance +) { + + private val cartesianPosition by lazy { + val x = distance * sin(declination) * cos(rightAscension) + val y = distance * sin(declination) * sin(rightAscension) + val z = distance * cos(declination) + Vector3d(x.meters, y.meters, z.meters) + } + + // What? I'm not afraid of a few trigonometric functions and a square root or two + fun distanceTo(other: SphericalVector): Distance { + return cartesianPosition.distance(other.cartesianPosition).meters + } +} \ No newline at end of file diff --git a/src/test/kotlin/io/github/addoncommunity/test/api/objects/properties/OrbitTest.kt b/src/test/kotlin/io/github/addoncommunity/test/api/objects/properties/OrbitTest.kt index aac7134..77e80e9 100644 --- a/src/test/kotlin/io/github/addoncommunity/test/api/objects/properties/OrbitTest.kt +++ b/src/test/kotlin/io/github/addoncommunity/test/api/objects/properties/OrbitTest.kt @@ -1,27 +1,66 @@ package io.github.addoncommunity.test.api.objects.properties import io.github.addoncommunity.galactifun.api.objects.properties.Orbit +import io.github.addoncommunity.galactifun.api.objects.properties.visVivaEquation import io.github.addoncommunity.galactifun.base.BaseUniverse +import io.github.addoncommunity.galactifun.units.Angle import io.github.addoncommunity.galactifun.units.Angle.Companion.degrees -import io.github.addoncommunity.galactifun.units.Distance.Companion.kilometers +import io.github.addoncommunity.galactifun.units.Distance.Companion.au import io.github.addoncommunity.test.CommonTest +import io.kotest.matchers.doubles.percent +import io.kotest.matchers.doubles.plusOrMinus +import io.kotest.matchers.shouldBe import kotlinx.datetime.Instant +import org.junit.jupiter.api.BeforeEach import kotlin.test.Test -import kotlin.time.Duration.Companion.minutes +import kotlin.time.DurationUnit class OrbitTest : CommonTest() { - @Test - fun testOrbit() { - val orbit = Orbit( - parent = BaseUniverse.earth, - semimajorAxis = 1000.0.kilometers, - eccentricity = 1e-8, + lateinit var orbit: Orbit + + @BeforeEach + fun setUpOrbit() { + orbit = Orbit( + parent = BaseUniverse.sun, + semimajorAxis = 1.0.au, + eccentricity = Orbit.TINY_ECCENTRICITY, argumentOfPeriapsis = 0.0.degrees, - timeOfPeriapsis = Instant.fromEpochMilliseconds(0) + timeOfPeriapsis = Instant.parse("1970-01-01T12:00:00Z") ) - val time = Instant.fromEpochMilliseconds(0) - println(orbit.trueAnomaly(time)) - println(orbit.trueAnomaly(time + 20.minutes)) + Orbit.TIME_SCALE = 1.0 } -} \ No newline at end of file + + @Test + fun testPeriod() { + orbit.period.toDouble(DurationUnit.DAYS) shouldBeRoughly 365.26 + } + + @Test + fun testPosition() { + val time = orbit.timeOfPeriapsis + val pos = orbit.position(time) + pos.radius shouldBe orbit.radius(time) + } + + @Test + fun testVelocity() { + fun testVelocityAt(time: Instant, expectedAngle: Angle) { + val vel = orbit.velocity(time) + println(vel) + vel.length.meters shouldBeRoughly visVivaEquation( + orbit.parent.gravitationalParameter, + orbit.radius(orbit.timeOfPeriapsis), + orbit.semimajorAxis + ) + vel.polar.angle.standardForm.degrees shouldBeRoughly expectedAngle.degrees + } + + testVelocityAt(orbit.timeOfPeriapsis, 90.0.degrees) + testVelocityAt(orbit.timeOfPeriapsis + orbit.period, 90.0.degrees) + testVelocityAt(orbit.timeOfPeriapsis + orbit.period / 2, 270.0.degrees) + testVelocityAt(orbit.timeOfPeriapsis + orbit.period / 4, 180.0.degrees) + } +} + +infix fun Double.shouldBeRoughly(expected: Double) = this shouldBe expected.plusOrMinus(1.percent) \ No newline at end of file