aboutsummaryrefslogtreecommitdiffstats
path: root/site
diff options
context:
space:
mode:
Diffstat (limited to 'site')
-rw-r--r--site/favicon.icobin0 -> 1258 bytes
-rw-r--r--site/index.html25
-rw-r--r--site/main.css11
-rw-r--r--site/main.mjs140
4 files changed, 176 insertions, 0 deletions
diff --git a/site/favicon.ico b/site/favicon.ico
new file mode 100644
index 0000000..73de524
--- /dev/null
+++ b/site/favicon.ico
Binary files differ
diff --git a/site/index.html b/site/index.html
new file mode 100644
index 0000000..012e301
--- /dev/null
+++ b/site/index.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang='en-US'>
+ <head>
+ <meta charset='utf-8'>
+ <title>polyring</title>
+ <link rel='stylesheet' href='main.css'>
+ <meta name='viewport' content='width=device-width'>
+ </head>
+
+ <body>
+ <h1>polyring</h1>
+ <p>benchmarking maximal convex polygon finding</p>
+
+ <button>go</button>
+ <span>fps: <span id='fps'>n/a</span></span>
+ <br>
+ <canvas width='500' height='500'></canvas>
+
+ <script src='./main.mjs' type='module'></script>
+
+ <footer>
+ <address><a href='https://git.spork.org/polyring.git'>src</a></address>
+ </footer>
+ </body>
+</html>
diff --git a/site/main.css b/site/main.css
new file mode 100644
index 0000000..f875232
--- /dev/null
+++ b/site/main.css
@@ -0,0 +1,11 @@
+html {
+ box-sizing: border-box;
+}
+*, *::before, *::after {
+ box-sizing: inherit;
+}
+
+canvas {
+ border: 1px solid orangered;
+ background-color: rgb(200 200 200);
+}
diff --git a/site/main.mjs b/site/main.mjs
new file mode 100644
index 0000000..0c81b41
--- /dev/null
+++ b/site/main.mjs
@@ -0,0 +1,140 @@
+const NUM_POINTS = 5;
+
+// 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();
+
+ #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;
+ }
+}
+
+const points = [...Array(NUM_POINTS)].map(_ => new Point());
+
+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.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, 'points:', points);
+ 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;
+ function render(t) {
+ if (t > lastTime) {
+ fps.textContent = Math.floor(1_000 / (t - lastTime));
+ lastTime = t;
+ }
+
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ renderPoints(ctx, points);
+ if (bouncePoints(points)) {
+ //goButton.onclick({ target: goButton });
+ }
+ movePoints(points);
+
+ if (!paused) {
+ self.requestAnimationFrame(render);
+ }
+ }
+
+ //goButton.onclick({ target: goButton });
+ render(document.timeline.currentTime);
+}
+
+document.addEventListener('DOMContentLoaded', loaded);