Fix ball on springs demo
This commit is contained in:
parent
9f21a14f96
commit
1799a9a909
@ -26,17 +26,23 @@ public class MaterialPoint(
|
|||||||
private var currentForce = force.value
|
private var currentForce = force.value
|
||||||
|
|
||||||
private val movement = onTimer(
|
private val movement = onTimer(
|
||||||
|
DefaultTimer.REALTIME,
|
||||||
reads = setOf(velocity, position),
|
reads = setOf(velocity, position),
|
||||||
writes = setOf(velocity, position)
|
writes = setOf(velocity, position)
|
||||||
) { prev, next ->
|
) { prev, next ->
|
||||||
val dtSeconds = (next - prev).toDouble(DurationUnit.SECONDS)
|
val dtSeconds = (next - prev).toDouble(DurationUnit.SECONDS)
|
||||||
|
|
||||||
// compute new value based on velocity and acceleration from the previous step
|
// compute new value based on velocity and acceleration from the previous step
|
||||||
position.value += (velocity.value * dtSeconds).cast(Meters) +
|
val deltaR = (velocity.value * dtSeconds).cast(Meters) +
|
||||||
(currentForce / mass.value * dtSeconds.pow(2) / 2).cast(Meters)
|
(currentForce / mass.value * dtSeconds.pow(2) / 2).cast(Meters)
|
||||||
|
position.value += deltaR
|
||||||
|
|
||||||
// compute new velocity based on acceleration on the previous step
|
// compute new velocity based on acceleration on the previous step
|
||||||
velocity.value += (currentForce / mass.value * dtSeconds).cast(MetersPerSecond)
|
val deltaV = (currentForce / mass.value * dtSeconds).cast(MetersPerSecond)
|
||||||
|
//TODO apply energy correction
|
||||||
|
//val work = deltaR.length.value * currentForce.length.value
|
||||||
|
velocity.value += deltaV
|
||||||
|
|
||||||
currentForce = force.value
|
currentForce = force.value
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package space.kscience.controls.constructor.units
|
package space.kscience.controls.constructor.units
|
||||||
|
|
||||||
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
public data class XY<U : UnitsOfMeasurement>(val x: NumericalValue<U>, val y: NumericalValue<U>)
|
public data class XY<U : UnitsOfMeasurement>(val x: NumericalValue<U>, val y: NumericalValue<U>)
|
||||||
|
|
||||||
public fun <U : UnitsOfMeasurement> XY(x: Number, y: Number): XY<U> = XY(NumericalValue(x), NumericalValue((y)))
|
public fun <U : UnitsOfMeasurement> XY(x: Number, y: Number): XY<U> = XY(NumericalValue(x), NumericalValue((y)))
|
||||||
@ -18,6 +21,11 @@ public data class XYZ<U : UnitsOfMeasurement>(
|
|||||||
val z: NumericalValue<U>,
|
val z: NumericalValue<U>,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
public val <U : UnitsOfMeasurement> XYZ<U>.length: NumericalValue<U>
|
||||||
|
get() = NumericalValue(
|
||||||
|
sqrt(x.value.pow(2) + y.value.pow(2) + z.value.pow(2))
|
||||||
|
)
|
||||||
|
|
||||||
public fun <U : UnitsOfMeasurement> XYZ(x: Number, y: Number, z: Number): XYZ<U> =
|
public fun <U : UnitsOfMeasurement> XYZ(x: Number, y: Number, z: Number): XYZ<U> =
|
||||||
XYZ(NumericalValue(x), NumericalValue((y)), NumericalValue(z))
|
XYZ(NumericalValue(x), NumericalValue((y)), NumericalValue(z))
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ import space.kscience.controls.constructor.models.MaterialPoint
|
|||||||
import space.kscience.controls.constructor.units.*
|
import space.kscience.controls.constructor.units.*
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import kotlin.math.pow
|
|
||||||
import kotlin.math.sqrt
|
|
||||||
|
|
||||||
|
|
||||||
private class Spring(
|
private class Spring(
|
||||||
@ -33,7 +31,7 @@ private class Spring(
|
|||||||
*/
|
*/
|
||||||
val tension: DeviceState<XYZ<Newtons>> = combineState(begin, end) { begin: XYZ<Meters>, end: XYZ<Meters> ->
|
val tension: DeviceState<XYZ<Newtons>> = combineState(begin, end) { begin: XYZ<Meters>, end: XYZ<Meters> ->
|
||||||
val delta = end - begin
|
val delta = end - begin
|
||||||
val l = sqrt(delta.x.value.pow(2) + delta.y.value.pow(2) + delta.z.value.pow(2))
|
val l = delta.length.value
|
||||||
((delta / l) * k * (l - l0.value)).cast(Newtons)
|
((delta / l) * k * (l - l0.value)).cast(Newtons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +85,7 @@ private class BodyOnSprings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main() = application {
|
fun main() = application {
|
||||||
val initialState = XYZ<Meters>(0.01, 0.1, 0)
|
val initialState = XYZ<Meters>(0, 0.4, 0)
|
||||||
|
|
||||||
Window(title = "Ball on springs", onCloseRequest = ::exitApplication) {
|
Window(title = "Ball on springs", onCloseRequest = ::exitApplication) {
|
||||||
window.minimumSize = Dimension(400, 400)
|
window.minimumSize = Dimension(400, 400)
|
||||||
|
Loading…
Reference in New Issue
Block a user