Created
September 14, 2021 10:25
-
-
Save LouisCAD/946f2261682ca09ed081fd1e2accbdd9 to your computer and use it in GitHub Desktop.
A partial double precision floating point based implementation of the Système International of Units.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:Suppress("experimental_is_not_enabled") | |
@file:OptIn(ExperimentalTime::class) | |
import kotlin.math.sqrt | |
import kotlin.time.Duration | |
import kotlin.time.DurationUnit | |
import kotlin.time.ExperimentalTime | |
//// Metrics | |
@JvmInline | |
value class Distance(val meters: Double) { | |
operator fun plus(other: Distance): Distance { | |
return Distance(meters = meters + other.meters) | |
} | |
@ExperimentalTime | |
operator fun div(time: Duration): Speed { | |
val seconds = time.toDouble(DurationUnit.SECONDS) | |
return Speed(metersPerSecond = meters / seconds) | |
} | |
companion object { | |
fun meters(value: Double): Distance = Distance(meters = value) | |
} | |
} | |
@JvmInline | |
value class Speed(val metersPerSecond: Double) { | |
@ExperimentalTime | |
operator fun div(time: Duration): Acceleration { | |
val seconds = time.toDouble(DurationUnit.SECONDS) | |
return Acceleration(metersPerSecondPerSecond = metersPerSecond / seconds) | |
} | |
@ExperimentalTime | |
operator fun times(time: Duration): Distance { | |
val seconds = time.toDouble(DurationUnit.SECONDS) | |
return Distance(meters = metersPerSecond * seconds) | |
} | |
@ExperimentalTime | |
operator fun div(acceleration: Acceleration): Duration { | |
return Duration.seconds(metersPerSecond / acceleration.metersPerSecondPerSecond) | |
} | |
companion object { | |
val None = Speed(metersPerSecond = 0.0) | |
fun metersPerSecond(value: Double): Speed { | |
return Speed(metersPerSecond = value) | |
} | |
} | |
} | |
@JvmInline | |
value class Acceleration(val metersPerSecondPerSecond: Double) { | |
@ExperimentalTime | |
operator fun times(time: Duration): Speed { | |
val seconds = time.toDouble(DurationUnit.SECONDS) | |
return Speed(metersPerSecond = metersPerSecondPerSecond * seconds) | |
} | |
companion object { | |
val GravityEarth = metersPerSecondPerSecond(9.80665) | |
fun metersPerSecondPerSecond(value: Double): Acceleration { | |
return Acceleration(metersPerSecondPerSecond = value) | |
} | |
} | |
} | |
//// Operators | |
operator fun Double.times(acceleration: Acceleration): Acceleration { | |
return Acceleration( | |
metersPerSecondPerSecond = acceleration.metersPerSecondPerSecond * this | |
) | |
} | |
//// Formulas | |
@ExperimentalTime | |
fun distanceTravelled( | |
initialVelocity: Speed, | |
acceleration: Acceleration, | |
time: Duration | |
): Distance { | |
return initialVelocity * time + (1.0 / 2.0) * acceleration * time * time | |
} | |
@ExperimentalTime | |
fun timeToTravel( | |
initialVelocity: Speed, | |
acceleration: Acceleration, | |
distance: Distance | |
): Duration { | |
val a = acceleration.metersPerSecondPerSecond | |
val d = distance.meters | |
val vi = initialVelocity.metersPerSecond | |
return Duration.seconds((sqrt((2.0 * a * d + vi * vi)) - vi) / a) | |
} | |
@ExperimentalTime | |
fun timeToFallOnEarth(distance: Distance): Duration { | |
return timeToTravel( | |
initialVelocity = Speed.None, | |
acceleration = Acceleration.GravityEarth, | |
distance = distance | |
) | |
} | |
//// Tests | |
@OptIn(ExperimentalTime::class) | |
println(Speed(metersPerSecond = 100.0) * Duration.seconds(2)) | |
@OptIn(ExperimentalTime::class) | |
val distance = distanceTravelled( | |
initialVelocity = Speed.None, | |
acceleration = Acceleration.GravityEarth, | |
time = Duration.milliseconds(770) | |
) | |
println(distance) | |
@OptIn(ExperimentalTime::class) | |
val time = timeToTravel( | |
initialVelocity = Speed.None, | |
acceleration = Acceleration.GravityEarth, | |
distance = distance | |
).inWholeMilliseconds | |
println(time) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment