aboutsummaryrefslogtreecommitdiffstats
path: root/site/main.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'site/main.mjs')
-rw-r--r--site/main.mjs261
1 files changed, 0 insertions, 261 deletions
diff --git a/site/main.mjs b/site/main.mjs
deleted file mode 100644
index dc67d73..0000000
--- a/site/main.mjs
+++ /dev/null
@@ -1,261 +0,0 @@
-const NUM_POINTS = 40;
-
-// thanks vihart
-const TAU = 2 * Math.PI;
-
-// no more than 1% of world size per tick.
-const MAX_SPEED = 0.01;
-
-// size of rendered points in proportion to canvas.
-const POINT_RADIUS = 0.01;
-
-class Point {
- x = Math.random();
- y = Math.random();
- #heading = Math.random() * TAU;
- speed = Math.random() * MAX_SPEED;
- color = randColor();
-
- constructor(x = Math.random(), y = Math.random()) {
- this.x = x;
- this.y = y;
- }
-
- equalPos(other) {
- return this.x === other.x && this.y === other.y;
- }
-
- dot(other) {
- return this.x * other.x + this.y * other.y;
- }
-
- get mag() {
- return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
- }
-
- #speedX;
- get speedX() {
- if (this.#speedX === undefined) {
- this.#speedX = this.speed * Math.cos(this.heading);
- }
- return this.#speedX;
- }
-
- #speedY;
- get speedY() {
- if (this.#speedY === undefined) {
- this.#speedY = this.speed * Math.sin(this.heading);
- }
- return this.#speedY;
- }
-
- get heading() {
- return this.#heading;
- }
-
- set heading(val) {
- this.#heading = val;
- this.#speedX = this.#speedY = undefined;
- }
-
- toString() {
- return `(${this.x.toFixed(2)}, ${this.y.toFixed(2)})`
- }
-}
-
-class Line {
- constructor(p1, p2) {
- this.p1 = p1;
- this.p2 = p2;
- }
-
- get vec() {
- return new Point(this.p2.x - this.p1.x, this.p2.y - this.p1.y)
- }
-
- angleBetween(other) {
- // console.debug(' angleBetween', this.toString(), other.toString());
- const v1 = this.vec;
- const v2 = other.vec;
- // console.debug(` dot of ${v1} * ${v2}`, v1.dot(v2));
- // console.debug(` mag of ${v1} * ${v2}`, v1.mag * v2.mag);
- const theta = Math.acos(v1.dot(v2) / (v1.mag * v2.mag));
- // console.debug(` theta is`, 360 * theta / TAU);
- return theta;
- }
- angleBetween2(other) {
- console.debug('angleBetween',
- `(${this.p1.x}, ${this.p1.y})-(${this.p2.x}, ${this.p2.y})`,
- `(${other.p1.x}, ${other.p1.y})-(${other.p2.x}, ${other.p2.y})`,
- );
- return Math.atan(Math.abs((this.slope - other.slope) / (1 + this.slope * other.slope)))
- }
-
- get slope() {
- return (this.p2.y - this.p1.y) / (this.p2.x - this.p1.x);
- }
-
- toString() {
- return `${this.p1}-${this.p2}`;
- }
-}
-
-// assume points is sorted min first.
-function findPoly3(points) {
- // console.debug('findPoly()', ...points.map(p => { return {x: p.x, y: p.y} }));
-
- let lastLine = new Line(new Point(0, 0), new Point(1, 0));
- // console.debug('horiz slope', lastLine.slope);
-
- // bail out counter. shouldn't be necessary, but who knows.
- let xxx = 100;
- let res = [points[0]];
- do {
- // last result is always a point on the edge.
- const p1 = res[res.length-1];
- // console.debug(`-- checking lines from ${p1}`);
- let last = res[res.length-1];
- let minTheta = TAU;
- let minP = points[0];
- for (let i = 0; i < points.length; i++) {
- if (!last.equalPos(points[i])) {
- let l2 = new Line(last, points[i]);
- let theta = lastLine.angleBetween(l2);
- // console.debug('+++ l2 slope', l2.slope, theta, 360 * theta / TAU);
- if (theta < minTheta) {
- // console.debug(' -- min angle')
- minTheta = theta;
- minP = points[i];
- }
- }
- }
- lastLine = new Line(res[res.length-1], minP);
- res.push(minP);
- // console.debug('term', xxx, res[0].x, res[0].y, res[res.length-1].x, res[res.length-1].y)
- } while (xxx-- > 0 && !res[0].equalPos(res[res.length-1]));
- if (xxx === 0) {
- alert('couldn\'t find your polycule');
- }
-
- // console.debug('findPoly res', res);
- return res;
-}
-
-const points = [...Array(NUM_POINTS)].map(_ => new Point());
-// const points = [
-// new Point(0.5, 0.1),
-// new Point(0.75, 0.2),
-// new Point(0.9, 0.9),
-// new Point(0.2, 0.5),
-// new Point(0.6, 0.4), // should be inside
-// ];
-
-function randColor() {
- const [r, g, b] = [...Array(3)].map(_ => Math.random() * 255);
- return `rgb(${r} ${g} ${b})`
-}
-
-function renderPoints(ctx, points) {
- points.forEach(p => {
- ctx.fillStyle = p.color;
- ctx.beginPath();
- ctx.arc(p.x, p.y, POINT_RADIUS, 0, TAU);
- ctx.fill();
-
- ctx.strokeStyle = p.color;
- ctx.lineWidth = 0.005;
- ctx.beginPath();
- ctx.moveTo(p.x, p.y);
- ctx.lineTo(p.x + p.speedX * 3, p.y + p.speedY * 3);
- ctx.stroke();
- });
-}
-
-function movePoints(points) {
- points.forEach(p => {
- p.x += p.speedX;
- p.y += p.speedY;
- });
-}
-
-function bouncePoints(points) {
- let didBounce = false;
- points.forEach(p => {
- const x = p.x + p.speedX;
- const y = p.y + p.speedY;
-
- if (x < 0) {
- p.heading = Math.PI - p.heading;
- didBounce = true;
- } else if (x >= 1) {
- p.heading = Math.PI - p.heading;
- didBounce = true;
- } else if (y < 0) {
- p.heading = -1 * p.heading;
- didBounce = true;
- } else if (y >= 1) {
- p.heading = -1 * p.heading;
- didBounce = true;
- }
- });
- return didBounce;
-}
-
-async function loaded() {
- const canvas = document.querySelector('canvas');
- const ctx = canvas.getContext('2d');
- console.debug('canvas:', canvas, 'ctx', ctx);
- ctx.scale(canvas.width, canvas.height);
-
- const fps = document.querySelector('#fps');
-
- const goButton = document.querySelector('button');
- let paused = true;
- goButton.onclick = e => {
- paused = !paused;
- if (paused) {
- e.target.textContent = 'go';
- } else {
- e.target.textContent = 'pause';
- self.requestAnimationFrame(render);
- }
- };
-
- let lastTime = document.timeline.currentTime;
- let interCount = 0;
- function render(t) {
- if (t > lastTime) {
- fps.textContent = Math.floor(1_000 * interCount / (t - lastTime));
- lastTime = t;
- interCount = 0;
- } else {
- interCount++;
- }
-
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- renderPoints(ctx, points);
- if (bouncePoints(points)) {
- //goButton.onclick({ target: goButton });
- }
- movePoints(points);
-
- points.sort((a, b) => a.y > b.y);
- const polyPoints = findPoly3(points);
-
- ctx.lineWidth = 0.005;
- ctx.beginPath();
- ctx.moveTo(polyPoints[0].x, polyPoints[0].y);
- polyPoints.forEach(p => ctx.lineTo(p.x, p.y));
- ctx.strokeStyle = 'blue';
- ctx.stroke();
-
- if (!paused) {
- self.requestAnimationFrame(render);
- }
- }
-
- //goButton.onclick({ target: goButton });
- render(document.timeline.currentTime);
-}
-
-document.addEventListener('DOMContentLoaded', loaded);