Skip to content

Commit 0d0570d

Browse files
committed
[orx-force-2d] Add DemoGraphLayout01.kt
1 parent 9063880 commit 0d0570d

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

orx-force-2d/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ kotlin {
2323
implementation(project(":orx-shapes"))
2424
implementation(project(":orx-color"))
2525
implementation(project(":orx-noise"))
26+
implementation(project(":orx-kdtree"))
2627
}
2728
}
2829
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import kotlinx.coroutines.runBlocking
2+
import org.openrndr.application
3+
import org.openrndr.color.ColorRGBa
4+
import org.openrndr.extra.force2d.Body
5+
import org.openrndr.extra.force2d.ForceSimulation
6+
import org.openrndr.extra.force2d.Link
7+
import org.openrndr.extra.force2d.Node
8+
import org.openrndr.extra.force2d.linkLengthConstraint
9+
import org.openrndr.extra.force2d.nodeRepulseForce
10+
import org.openrndr.extra.force2d.rectangularBoundsConstraint
11+
import org.openrndr.extra.kdtree.kdTree
12+
import org.openrndr.extra.noise.scatter
13+
import org.openrndr.math.Vector2
14+
import org.openrndr.shape.LineSegment
15+
16+
/**
17+
* Demonstrates a simple force graph layout
18+
*/
19+
fun main() {
20+
application {
21+
configure {
22+
width = 720
23+
height = 720
24+
}
25+
program {
26+
val pts = drawer.bounds.scatter(20.0)
27+
val index = pts.mapIndexed { index, vector2 -> vector2 to index }.toMap()
28+
val kd = pts.kdTree()
29+
30+
val nodes = pts.map {
31+
Node(it, it, Vector2.ZERO, radius = 4.0)
32+
}
33+
34+
val links = pts.flatMapIndexed { source, it ->
35+
kd.findKNearest(it, 2).map {
36+
val idx = index.getValue(it)
37+
Link(source, idx)
38+
}
39+
}
40+
41+
val body = Body(nodes, links = links).apply {
42+
linkLengthConstraint {
43+
compliance = 1E-1
44+
45+
}
46+
nodeRepulseForce {
47+
searchRadius = 100.0
48+
strength = 10.0
49+
}
50+
rectangularBoundsConstraint {
51+
bounds = drawer.bounds.offsetEdges(-10.0)
52+
}
53+
}
54+
55+
val sim = ForceSimulation(mutableListOf(body))
56+
57+
extend {
58+
runBlocking {
59+
sim.simulate(1.0 / 60.0, 10)
60+
}
61+
62+
drawer.stroke = ColorRGBa.PINK
63+
drawer.lineSegments(body.links.map {
64+
LineSegment(body.nodes[it.source].position, body.nodes[it.target].position)
65+
})
66+
67+
drawer.circles(body.nodes.map { it.position }, 4.0)
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)