2023-12-18 09:41:05 +03:00
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
|
import androidx.compose.runtime.remember
|
2024-02-07 18:11:49 +03:00
|
|
|
import app.softwork.bootstrapcompose.Column
|
|
|
|
import app.softwork.bootstrapcompose.Row
|
2021-08-18 11:39:37 +03:00
|
|
|
import kotlinx.coroutines.delay
|
|
|
|
import kotlinx.coroutines.isActive
|
2023-12-18 09:41:05 +03:00
|
|
|
import org.jetbrains.compose.web.css.*
|
|
|
|
import org.jetbrains.compose.web.dom.AttrBuilderContext
|
|
|
|
import org.jetbrains.compose.web.dom.Div
|
|
|
|
import org.w3c.dom.HTMLDivElement
|
2024-02-07 18:11:49 +03:00
|
|
|
import space.kscience.dataforge.context.Context
|
2023-12-18 09:41:05 +03:00
|
|
|
import space.kscience.dataforge.meta.Meta
|
|
|
|
import space.kscience.plotly.Plot
|
2021-08-18 23:02:17 +03:00
|
|
|
import space.kscience.plotly.layout
|
2021-08-18 11:39:37 +03:00
|
|
|
import space.kscience.plotly.models.Trace
|
2022-01-27 12:10:00 +03:00
|
|
|
import space.kscience.visionforge.Colors
|
2024-02-12 16:44:15 +03:00
|
|
|
import space.kscience.visionforge.html.Vision
|
|
|
|
import space.kscience.visionforge.html.zIndex
|
2021-08-18 11:39:37 +03:00
|
|
|
import space.kscience.visionforge.markup.VisionOfMarkup
|
2023-12-18 09:41:05 +03:00
|
|
|
import space.kscience.visionforge.plotly.asVision
|
2021-08-18 11:39:37 +03:00
|
|
|
import space.kscience.visionforge.solid.*
|
2023-12-18 09:41:05 +03:00
|
|
|
import space.kscience.visionforge.solid.three.compose.ThreeView
|
2021-08-18 11:39:37 +03:00
|
|
|
import kotlin.math.sqrt
|
|
|
|
|
2023-12-18 09:41:05 +03:00
|
|
|
@Composable
|
|
|
|
fun Plot(
|
2024-02-07 18:11:49 +03:00
|
|
|
context: Context,
|
2023-12-18 09:41:05 +03:00
|
|
|
meta: Meta = Meta.EMPTY,
|
|
|
|
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
|
|
|
block: Plot.() -> Unit,
|
|
|
|
) = Vision(
|
2024-02-07 18:11:49 +03:00
|
|
|
context = context,
|
2023-12-18 09:41:05 +03:00
|
|
|
attrs = attrs,
|
|
|
|
meta = meta,
|
|
|
|
vision = Plot().apply(block).asVision()
|
|
|
|
)
|
2021-08-18 11:39:37 +03:00
|
|
|
|
2023-12-18 09:41:05 +03:00
|
|
|
@Composable
|
|
|
|
fun Markup(
|
2024-02-07 18:11:49 +03:00
|
|
|
context: Context,
|
2023-12-18 09:41:05 +03:00
|
|
|
markup: VisionOfMarkup,
|
|
|
|
meta: Meta = Meta.EMPTY,
|
|
|
|
attrs: AttrBuilderContext<HTMLDivElement>? = null,
|
|
|
|
) = Vision(
|
2024-02-07 18:11:49 +03:00
|
|
|
context = context,
|
2023-12-18 09:41:05 +03:00
|
|
|
attrs = attrs,
|
|
|
|
meta = meta,
|
|
|
|
vision = markup
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
private val h = 100.0
|
|
|
|
|
|
|
|
@Composable
|
2024-02-07 18:11:49 +03:00
|
|
|
fun GravityDemo(context: Context) {
|
2023-12-18 09:41:05 +03:00
|
|
|
val velocityTrace = remember {
|
|
|
|
Trace {
|
|
|
|
name = "velocity"
|
|
|
|
}
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
|
|
|
|
2023-12-18 09:41:05 +03:00
|
|
|
val energyTrace = remember {
|
|
|
|
Trace {
|
|
|
|
name = "energy"
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
2023-12-18 09:41:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
val markup = remember { VisionOfMarkup() }
|
|
|
|
|
|
|
|
val solid = remember {
|
|
|
|
SolidGroup {
|
|
|
|
pointLight(200, 200, 200, name = "light") {
|
|
|
|
color(Colors.white)
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
2023-12-18 09:41:05 +03:00
|
|
|
ambientLight()
|
|
|
|
|
|
|
|
sphere(5.0, "ball") {
|
|
|
|
detail = 16
|
|
|
|
color("red")
|
|
|
|
y = h
|
|
|
|
|
|
|
|
|
|
|
|
box(200, 5, 200, name = "floor") {
|
|
|
|
y = -2.5
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-18 09:41:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
LaunchedEffect(solid) {
|
|
|
|
val ball = solid["ball"]!!
|
|
|
|
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 * ball.y.toDouble() + velocity * velocity / 2
|
|
|
|
ball.y = ball.y.toDouble() + velocity * dt
|
|
|
|
|
|
|
|
velocityTrace.appendXYLatest(time, ball.y)
|
|
|
|
energyTrace.appendXYLatest(time, energy)
|
|
|
|
|
|
|
|
if (ball.y.toDouble() <= 2.5) {
|
|
|
|
//conservation of energy
|
|
|
|
velocity = sqrt(2 * g * h)
|
|
|
|
}
|
|
|
|
|
|
|
|
markup.content = """
|
|
|
|
## Bouncing sphere parameters
|
|
|
|
|
|
|
|
**velocity** = $velocity
|
|
|
|
|
|
|
|
**energy** = $energy
|
|
|
|
""".trimIndent()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Div({
|
|
|
|
style {
|
|
|
|
height(100.vh - 50.pt)
|
|
|
|
}
|
|
|
|
}) {
|
|
|
|
Div({
|
|
|
|
style {
|
|
|
|
height(50.vh)
|
|
|
|
}
|
|
|
|
}) {
|
2024-02-07 18:11:49 +03:00
|
|
|
ThreeView(context, solid)
|
2023-12-18 09:41:05 +03:00
|
|
|
}
|
2024-02-07 18:11:49 +03:00
|
|
|
Row(attrs = {
|
2023-12-18 09:41:05 +03:00
|
|
|
style {
|
|
|
|
alignContent(AlignContent.Stretch)
|
|
|
|
alignItems(AlignItems.Stretch)
|
|
|
|
height(50.vh - 50.pt)
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
2023-12-18 09:41:05 +03:00
|
|
|
}) {
|
2024-02-07 18:11:49 +03:00
|
|
|
Column {
|
|
|
|
Plot(context) {
|
|
|
|
traces(velocityTrace, energyTrace)
|
|
|
|
layout {
|
|
|
|
xaxis.title = "time"
|
|
|
|
}
|
2021-08-18 23:02:17 +03:00
|
|
|
}
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
2024-02-07 18:11:49 +03:00
|
|
|
Column {
|
|
|
|
Markup(context, markup, attrs = {
|
|
|
|
style {
|
|
|
|
width(100.percent)
|
|
|
|
height(100.percent)
|
|
|
|
border(2.pt, LineStyle.Solid, Color.blue)
|
|
|
|
paddingLeft(8.pt)
|
|
|
|
backgroundColor(Color.white)
|
|
|
|
flex(1)
|
|
|
|
zIndex(10000)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2021-08-18 11:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|