103 lines
3.3 KiB
Kotlin
103 lines
3.3 KiB
Kotlin
|
import kotlinx.coroutines.delay
|
||
|
import kotlinx.coroutines.isActive
|
||
|
import kotlinx.coroutines.launch
|
||
|
import kotlinx.css.*
|
||
|
import react.RProps
|
||
|
import react.child
|
||
|
import react.functionalComponent
|
||
|
import space.kscience.dataforge.context.Context
|
||
|
import space.kscience.plotly.models.Trace
|
||
|
import space.kscience.visionforge.markup.VisionOfMarkup
|
||
|
import space.kscience.visionforge.react.flexRow
|
||
|
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||
|
import space.kscience.visionforge.ring.solid
|
||
|
import space.kscience.visionforge.solid.*
|
||
|
import styled.css
|
||
|
import styled.styledDiv
|
||
|
import kotlin.math.sqrt
|
||
|
|
||
|
external interface DemoProps : RProps {
|
||
|
var context: Context
|
||
|
}
|
||
|
|
||
|
val GravityDemo = functionalComponent<DemoProps> { props ->
|
||
|
val velocityTrace = Trace{
|
||
|
name = "velocity"
|
||
|
}
|
||
|
val energyTrace = Trace{
|
||
|
name = "energy"
|
||
|
}
|
||
|
val markup = VisionOfMarkup()
|
||
|
|
||
|
styledDiv {
|
||
|
css {
|
||
|
height = 100.vh - 50.pt
|
||
|
}
|
||
|
styledDiv {
|
||
|
css {
|
||
|
height = 50.vh
|
||
|
}
|
||
|
child(ThreeCanvasWithControls) {
|
||
|
attrs {
|
||
|
context = props.context
|
||
|
solid {
|
||
|
sphere(5.0, "ball") {
|
||
|
detail = 16
|
||
|
color("red")
|
||
|
val h = 100.0
|
||
|
y = h
|
||
|
context.launch {
|
||
|
val g = 10.0
|
||
|
val dt = 0.1
|
||
|
var time = 0.0
|
||
|
var velocity = 0.0
|
||
|
while (isActive) {
|
||
|
delay(20)
|
||
|
time += dt
|
||
|
velocity -= g * dt
|
||
|
val energy = g * y.toDouble() + velocity * velocity / 2
|
||
|
y = y.toDouble() + velocity * dt
|
||
|
|
||
|
velocityTrace.appendXYLatest(time, y)
|
||
|
energyTrace.appendXYLatest(time, energy)
|
||
|
|
||
|
if (y.toDouble() <= 2.5) {
|
||
|
//conservation of energy
|
||
|
velocity = sqrt(2 * g * h)
|
||
|
}
|
||
|
|
||
|
markup.content = """
|
||
|
## Bouncing sphere parameters
|
||
|
|
||
|
**velocity** = $velocity
|
||
|
|
||
|
**energy** = $energy
|
||
|
""".trimIndent()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
box(200, 5, 200, name = "floor") {
|
||
|
y = -2.5
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
flexRow {
|
||
|
css {
|
||
|
alignContent = Align.stretch
|
||
|
alignItems = Align.stretch
|
||
|
height = 50.vh - 50.pt
|
||
|
}
|
||
|
plotly {
|
||
|
traces(velocityTrace)
|
||
|
}
|
||
|
Markup {
|
||
|
attrs {
|
||
|
this.markup = markup
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|