Skip to content

Commit 664c348

Browse files
committed
OrbitModel orbit.html
- new Orbit model & html: - models/OrbitModel.js - uielements/orbit.html, uielements/orbitElements.js - views2/orbit.html
1 parent 61d4580 commit 664c348

File tree

10 files changed

+464
-68
lines changed

10 files changed

+464
-68
lines changed

models/OrbitModel.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import Model from 'https://code.agentscript.org/src/Model.js'
2+
import * as util from 'https://code.agentscript.org/src/utils.js'
3+
4+
// Earth’s radius: 6,371,000 meters (6,371 km)
5+
// LEO height: 200,000 meters (200 km)
6+
// LEO as a percentage of Earth's radius: ~3.14%
7+
8+
let lastGravity = 0
9+
10+
export default class OrbitModel extends Model {
11+
earthRadius
12+
LEOHeight
13+
gravity
14+
15+
LEORadius
16+
orbitalVelocity
17+
18+
// gravity = 0.01 // Adjusted gravity for more realistic orbit
19+
xPosition = 1 // should be +/- 1
20+
vDirection = 1 // should be +/- 1
21+
22+
trail = []
23+
trailSize = 200
24+
25+
// ======================
26+
27+
// constructor() {
28+
// super() // use default world options.
29+
// }
30+
31+
setLEOHeight(fraction) {
32+
this.LEOHeight = fraction * this.world.maxX
33+
this.resetRocket()
34+
}
35+
36+
setEarthRadius(fraction) {
37+
this.earthRadius = fraction * this.world.maxX
38+
this.resetRocket()
39+
}
40+
41+
setGravity(fraction) {
42+
this.gravity = fraction
43+
this.resetRocket()
44+
}
45+
46+
resetRocket() {
47+
if (isNaN(this.earthRadius * this.LEOHeight * this.gravity)) return
48+
49+
this.LEORadius = this.earthRadius + this.LEOHeight
50+
this.orbitalVelocity = Math.sqrt(this.gravity * this.LEORadius)
51+
52+
this.rocket.setxy(0, this.xPosition * this.LEORadius)
53+
this.rocket.vx = this.vDirection * this.orbitalVelocity
54+
this.rocket.vy = 0
55+
}
56+
57+
setNodes() {
58+
const a1 = this.nodes.createOne(t => t.setxy(0, this.world.maxY))
59+
const a2 = this.nodes.createOne(t => t.setxy(0, this.world.minY))
60+
const a3 = this.nodes.createOne(t => t.setxy(this.world.maxX, 0))
61+
const a4 = this.nodes.createOne(t => t.setxy(this.world.minX, 0))
62+
this.links.createOne(a1, a2)
63+
this.links.createOne(a3, a4)
64+
}
65+
66+
setup() {
67+
// why does this fail?
68+
// this.turtles.setDefault('atEdge', 'bounce')
69+
70+
this.turtleBreeds('rockets earths trails nodes')
71+
72+
const earth = this.earths.createOne() // default: located at 0,0
73+
this.rocket = this.rockets.createOne()
74+
this.setNodes()
75+
76+
this.setLEOHeight(0.03)
77+
this.setEarthRadius(0.2)
78+
this.setGravity(0.01)
79+
}
80+
81+
step() {
82+
// const rocket = this.rocket
83+
const { rocket, trail, trailSize } = this
84+
85+
const distance = Math.sqrt(rocket.x ** 2 + rocket.y ** 2)
86+
const gravityForce =
87+
(this.gravity * this.earthRadius ** 2) / distance ** 2
88+
89+
if (lastGravity !== this.gravity)
90+
console.log('grav', this.gravity, gravityForce)
91+
lastGravity = this.gravity
92+
93+
// Normalize gravity direction
94+
const ux = -rocket.x / distance
95+
const uy = -rocket.y / distance
96+
97+
// Apply gravity acceleration
98+
rocket.vx += ux * gravityForce
99+
rocket.vy += uy * gravityForce
100+
101+
// Update position
102+
rocket.x += rocket.vx
103+
rocket.y += rocket.vy
104+
105+
// add a trail object
106+
trail.push(this.trails.createOne(t => t.setxy(rocket.x, rocket.y)))
107+
if (trail.length > trailSize) {
108+
trail.shift().die() // Limit trail length
109+
}
110+
}
111+
}

models/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Code | Run demo
1919
[life](https://github.com/backspaces/agentscript/tree/master/models/LifeModel.js#L1) | [https://code.agentscript.org/models/run.html?life](https://code.agentscript.org/models/run.html?life)
2020
[linkTravel](https://github.com/backspaces/agentscript/tree/master/models/LinkTravelModel.js#L1) | [https://code.agentscript.org/models/run.html?linkTravel](https://code.agentscript.org/models/run.html?linkTravel)
2121
[min](https://github.com/backspaces/agentscript/tree/master/models/MinModel.js#L1) | [https://code.agentscript.org/models/run.html?min](https://code.agentscript.org/models/run.html?min)
22+
[orbit](https://github.com/backspaces/agentscript/tree/master/models/OrbitModel.js#L1) | [https://code.agentscript.org/models/run.html?orbit](https://code.agentscript.org/models/run.html?orbit)
2223
[pheromone](https://github.com/backspaces/agentscript/tree/master/models/PheromoneModel.js#L1) | [https://code.agentscript.org/models/run.html?pheromone](https://code.agentscript.org/models/run.html?pheromone)
2324
[roads](https://github.com/backspaces/agentscript/tree/master/models/RoadsModel.js#L1) | [https://code.agentscript.org/models/run.html?roads](https://code.agentscript.org/models/run.html?roads)
2425
[shapes](https://github.com/backspaces/agentscript/tree/master/models/ShapesModel.js#L1) | [https://code.agentscript.org/models/run.html?shapes](https://code.agentscript.org/models/run.html?shapes)

src/TwoView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class TwoView {
3333

3434
const children = Array.from(div.children)
3535
const canvases = children.filter(child => util.isCanvas(child))
36-
console.log('div children: ', children, ' canvases', canvases)
36+
// console.log('div children: ', children, ' canvases', canvases)
3737
// util.toWindow({ children, canvases })
3838

3939
let can

uielements/orbit.html

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!DOCTYPE html>
2+
3+
<head>
4+
<title>Orbit</title>
5+
6+
<script type="module" src="./uielements.html.js"></script>
7+
<link rel="stylesheet" href="./uielements.css" />
8+
</head>
9+
10+
<body>
11+
12+
<script type="module">
13+
// ====== Import uielements.js, only additional import needed ======
14+
15+
import * as UI from './uielements.js'
16+
import elements from './orbitElements.js'
17+
18+
// ====== The views2 code as-is ======
19+
20+
import Animator from 'https://code.agentscript.org/src/Animator.js'
21+
import TwoDraw from 'https://code.agentscript.org/src/TwoDraw.js'
22+
import Model from '../models/OrbitModel.js'
23+
24+
const model = new Model()
25+
model.setup()
26+
27+
const isRocket = t => t.breed.name === 'rockets'
28+
const view = new TwoDraw(model, {
29+
div: 'modelDiv',
30+
patchSize: 25,
31+
drawOptions: {
32+
patchesColor: 'black',
33+
linksColor: 'red',
34+
turtlesShape: 'circle',
35+
turtlesSize: (t) => {
36+
if (t.breed.name === "rockets") return 0.5
37+
if (t.breed.name === "earths") return 2 * model.earthRadius
38+
return 0.17 // trails & nodes
39+
},
40+
turtlesColor: (t) => {
41+
if (t.breed.name === "rockets") return "yellow"
42+
if (t.breed.name === "earths") return "blue"
43+
return "orange" // trails & nodes
44+
},
45+
}
46+
})
47+
48+
const anim = new Animator(
49+
() => {
50+
model.step()
51+
view.draw()
52+
},
53+
-1, // 500, // how many steps
54+
30 // at fps steps/second
55+
)
56+
57+
// ====== Additional code for uielements usage ======
58+
59+
anim.stop() // let uielements start/stop animator
60+
anim.setSteps(-1) // in case you want to run forever
61+
62+
await UI.setAppState(model, view, anim) // connect model to uielements
63+
64+
// UI.createElements() // use minElements, editable
65+
UI.createElements(elements, true) // use elements from file, editable
66+
// UI.createElements(elements) // use elements from file, not editable
67+
68+
// console.log(JSON.stringify(elements));
69+
70+
// Object.assign(window, { model, view, anim })
71+
72+
</script>
73+
74+
<!-- <div id="modelDiv"></div>
75+
<div id="plotDiv"></div> -->
76+
<div id="modelDiv"></div>
77+
78+
</body>
79+
80+
</html>

uielements/orbitElements.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
export default [
2+
{
3+
"id": 1729270887157,
4+
"type": "output",
5+
"name": "ticks",
6+
"position": {
7+
"x": 342,
8+
"y": 21
9+
},
10+
"monitor": "model.ticks",
11+
"fps": "10",
12+
"command": null
13+
},
14+
{
15+
"id": 1729463191305,
16+
"type": "range",
17+
"name": "patchesSize",
18+
"command": "view.setValue('patchesSize', value)",
19+
"position": {
20+
"x": 172,
21+
"y": 21
22+
},
23+
"min": "1",
24+
"max": "30",
25+
"step": "1",
26+
"value": "20"
27+
},
28+
{
29+
"id": 1730141024864,
30+
"type": "checkbox",
31+
"name": "Run",
32+
"command": "checked ? anim.start() : anim.stop()",
33+
"position": {
34+
"x": 20,
35+
"y": 21
36+
},
37+
"checked": false
38+
},
39+
{
40+
"id": 1733442807622,
41+
"type": "dropdown",
42+
"name": "fps",
43+
"command": "anim.setFps(value)",
44+
"position": {
45+
"x": 100,
46+
"y": 21
47+
},
48+
"options": [
49+
"2",
50+
"5",
51+
"10",
52+
"20",
53+
"30",
54+
"60"
55+
],
56+
"selected": "30"
57+
},
58+
{
59+
"id": 1729535684833,
60+
"type": "button",
61+
"name": "Save",
62+
"command": "downloadJson()",
63+
"position": {
64+
"x": 405,
65+
"y": 21
66+
}
67+
},
68+
{
69+
"id": 1740081151576,
70+
"type": "button",
71+
"name": "Reset",
72+
"command": "reset()",
73+
"position": {
74+
"x": 472,
75+
"y": 20
76+
}
77+
},
78+
{
79+
"id": 1740082006239,
80+
"type": "range",
81+
"name": "LEOHeight",
82+
"command": "model.setLEOHeight(value)",
83+
"position": {
84+
"x": 23,
85+
"y": 130
86+
},
87+
"min": "0",
88+
"max": "0.1",
89+
"step": "0.01",
90+
"value": "0.03"
91+
},
92+
{
93+
"id": 1740092781037,
94+
"type": "range",
95+
"name": "earthRadius",
96+
"command": "model.setEarthRadius(value)",
97+
"position": {
98+
"x": 228,
99+
"y": 130
100+
},
101+
"min": "0.1",
102+
"max": "0.9",
103+
"step": "0.05",
104+
"value": "0.2"
105+
},
106+
{
107+
"id": 1740331647865,
108+
"type": "range",
109+
"name": "gravity",
110+
"command": "model.setGravity(value)",
111+
"position": {
112+
"x": 417,
113+
"y": 129
114+
},
115+
"min": "0.005",
116+
"max": "0.02",
117+
"step": "0.001",
118+
"value": "0.01"
119+
}
120+
]

0 commit comments

Comments
 (0)