init
This commit is contained in:
commit
c4a2c22b88
20
index.html
Normal file
20
index.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<!-- <link rel='stylesheet' type='text/css' media='screen' href='main.css'> -->
|
||||
<title>Orbital simalation</title>
|
||||
<script src="./orbital.js" type="module">
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="graph">
|
||||
<canvas id="canvas" width="800" height="600" style="border:1px solid #000000;" />
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
59
kepplerObject.js
Normal file
59
kepplerObject.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { Vector } from "./vector.js";
|
||||
|
||||
export class KepplerObject {
|
||||
constructor(name, mass, radius, position, velocity, color) {
|
||||
this.mass = mass;
|
||||
this.name = name;
|
||||
this.radius = radius;
|
||||
this.position = position;
|
||||
this.velocity = velocity;
|
||||
this.color = color;
|
||||
this.trails = [];
|
||||
}
|
||||
|
||||
draw(ctx) {
|
||||
for (let t of this.trails) {
|
||||
ctx.strokeStyle = this.color;
|
||||
ctx.moveTo(t.x, t.y);
|
||||
ctx.lineTo(t.x + 1, t.y + 1);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
ctx.strokeStyle = this.color;
|
||||
ctx.fillStyle = this.color;
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
track() {
|
||||
let maxTrack = 100;
|
||||
this.trails.push(this.position.copy());
|
||||
|
||||
if (this.trails.length > maxTrack) {
|
||||
this.trails = this.trails.slice(1, maxTrack);
|
||||
}
|
||||
}
|
||||
|
||||
attrackt(kepObj) {
|
||||
let f = this.getForce(kepObj);
|
||||
|
||||
let direction = new Vector(this.position.x - kepObj.position.x, this.position.y - kepObj.position.y).normalize();
|
||||
|
||||
let velocity = f / this.mass;
|
||||
this.velocity.x -= velocity * direction.x;
|
||||
this.velocity.y -= velocity * direction.y;
|
||||
}
|
||||
|
||||
move() {
|
||||
this.position.x += this.velocity.x;
|
||||
this.position.y += this.velocity.y;
|
||||
}
|
||||
|
||||
getForce(o2) {
|
||||
let G = 5;
|
||||
let dist = this.position.getDistance(o2.position);
|
||||
let f = G * (this.mass * o2.mass) / (dist * dist);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
58
orbital.js
Normal file
58
orbital.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { Vector } from './vector.js'
|
||||
import { KepplerObject } from './kepplerObject.js'
|
||||
import * as utils from './utils.js'
|
||||
|
||||
|
||||
let ctx;
|
||||
let planets = [];
|
||||
let G = 5;
|
||||
let sun = {};
|
||||
|
||||
function update(dt) {
|
||||
for (let p of planets) {
|
||||
p.track();
|
||||
p.attrackt(sun);
|
||||
p.move();
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
let canvas = document.getElementById("canvas");
|
||||
ctx = canvas.getContext("2d");
|
||||
|
||||
document.querySelector('#canvas').addEventListener('click', setPlanet)
|
||||
sun = new KepplerObject("sun", 100, 20, new Vector(canvas.clientWidth / 2, canvas.clientHeight / 2), new Vector(0, 0), "yellow");
|
||||
|
||||
window.requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
function addPlanet(position) {
|
||||
let startVel = Math.sqrt(2 * G * 10 / position.getDistance(sun.position));
|
||||
let colors = ['red', 'blue', 'pink', 'green', 'grey'];
|
||||
|
||||
startVel *= utils.random(1, 100) <= 10 ? -1 : 1;
|
||||
startVel *= 1.4;
|
||||
|
||||
let planet = new KepplerObject("planet", utils.random(5, 25), utils.random(5, 15), position, new Vector(startVel, startVel), colors[utils.random(0, colors.length)]);
|
||||
planets.push(planet);
|
||||
}
|
||||
|
||||
function setPlanet(event) {
|
||||
let position = new Vector(event.x, event.y);
|
||||
addPlanet(position);
|
||||
}
|
||||
|
||||
function draw(time) {
|
||||
let dt = utils.getDeltaTime(time);
|
||||
utils.clearScreen(ctx, '#000000');
|
||||
|
||||
sun.draw(ctx);
|
||||
|
||||
update(dt);
|
||||
|
||||
for (let p of planets) {
|
||||
p.draw(ctx);
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(draw);
|
||||
}
|
||||
22
utils.js
Normal file
22
utils.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
let dt = 0;
|
||||
let oldTime = 0;
|
||||
|
||||
export function clearScreen(ctx, color) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
||||
}
|
||||
|
||||
export function random(min, max) {
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
export function getDeltaTime(time) {
|
||||
dt = time - oldTime;
|
||||
oldTime = time;
|
||||
|
||||
if (dt != 0) {
|
||||
dt = dt * 0.001;
|
||||
}
|
||||
|
||||
return dt;
|
||||
}
|
||||
32
vector.js
Normal file
32
vector.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
export class Vector {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
normalize() {
|
||||
let length = this.getLength();
|
||||
return new Vector(this.x / length, this.y / length);
|
||||
}
|
||||
|
||||
getLength() {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
}
|
||||
|
||||
getDistance(target) {
|
||||
let v = new Vector(target.x - this.x, target.y - this.y);
|
||||
return v.getLength();
|
||||
}
|
||||
|
||||
dotProduct(vector) {
|
||||
return this.x * vector.x + this.y * vector.y;
|
||||
}
|
||||
|
||||
getAngle(vector) {
|
||||
return this.dotProduct(vector) / (this.getLength() * vector.getLength())
|
||||
}
|
||||
|
||||
copy() {
|
||||
return new Vector(this.x, this.y);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user