Skip to content

Commit

Permalink
Yay velocity vectors work
Browse files Browse the repository at this point in the history
  • Loading branch information
Seggan committed Feb 23, 2024
1 parent 4764841 commit 3fb4a86
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.addoncommunity.galactifun.util
package io.github.addoncommunity.galactifun

import org.bukkit.Location
import org.bukkit.World
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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))
Expand All @@ -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 {
Expand All @@ -53,32 +63,26 @@ 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 {
/**
* 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<E, C : Collection<E>>(
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ value class Angle private constructor(val radians: Double) : Comparable<Angle> {
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

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Distance> {
Expand Down Expand Up @@ -30,12 +29,8 @@ value class Distance private constructor(val meters: Double) : Comparable<Distan
}
}

init {
require(meters >= 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)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading

0 comments on commit 3fb4a86

Please sign in to comment.