aboutsummaryrefslogtreecommitdiff
path: root/web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2021-12-29 21:24:57 +0100
committerIlion Beyst <ilion.beyst@gmail.com>2021-12-29 21:25:29 +0100
commit0c6d978442b244ca3f29c1ffdd44b5007ae7ad93 (patch)
treebaae5fa459a49ecd362e548e0649e2f58c669a70 /web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts
parent3eeaab6cec70e7a06a99a1ac2662974f71064bee (diff)
downloadplanetwars.dev-0c6d978442b244ca3f29c1ffdd44b5007ae7ad93.tar.xz
planetwars.dev-0c6d978442b244ca3f29c1ffdd44b5007ae7ad93.zip
separate out visualizer library
Diffstat (limited to 'web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts')
-rw-r--r--web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts165
1 files changed, 0 insertions, 165 deletions
diff --git a/web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts b/web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts
deleted file mode 100644
index a63bc9a..0000000
--- a/web/pw-frontend/src/lib/visualizer/voronoi/voronoi.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import type { Shader } from "../webgl/shader";
-import type { BBox, Point } from "./voronoi-core";
-import Voronoi from "./voronoi-core";
-import { DefaultRenderable } from "../webgl/renderer";
-import { IndexBuffer, VertexBuffer } from "../webgl/buffer";
-import { VertexBufferLayout, VertexArray } from "../webgl/vertexBufferLayout";
-
-function arcctg(x: number): number { return Math.PI / 2 - Math.atan(x); }
-
-function to_key(p: Point): string {
- return [p.x, p.y] + "";
-}
-
-function round_point(center: Point, point: Point, amount_fn = (b: number) => 0.7): Point {
- const d = dist(center, point, true);
- const x = center.x + amount_fn(d) * (point.x - center.x);
- const y = center.y + amount_fn(d) * (point.y - center.y);
- return { 'x': x, 'y': y };
-}
-
-function median_point(c: Point, p: Point, n: Point, d = 0.1): number[] {
- const dd = 1.0 - 2 * d;
- return [
- dd * c.x + d * p.x + d * n.x,
- dd * c.y + d * p.y + d * n.y,
- ]
-}
-
-function build_point_map(es: Voronoi.HalfEdge[]): (point: Point) => Point {
- const mean = es.map(e => dist(e.getStartpoint(), e.getEndpoint())).reduce((a, b) => a + b, 0) / es.length;
- const map = {};
-
- for (let edge of es) {
- const start = edge.getStartpoint();
- const end = edge.getEndpoint();
-
- if (dist(start, end) < 0.03 * mean) { // These points have to be merged
- const middle = { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 };
- map[to_key(start)] = middle;
- map[to_key(end)] = middle;
- }
- }
-
- return (p) => map[to_key(p)] || p;
-}
-
-function get_round_fn(dist_mean: number, amount = 0.7): (d: number) => number {
- return (d) => arcctg((d - dist_mean) / dist_mean) / Math.PI + 0.6;
-}
-
-function dist(a: Point, b: Point, norm = false): number {
- const dx = a.x - b.x;
- const dy = a.y - b.y;
- if (norm) return Math.sqrt(dx * dx + dy * dy);
- return dx * dx + dy * dy;
-}
-
-export class VoronoiBuilder {
- inner: DefaultRenderable;
-
- vor: Voronoi;
- planets: Point[];
-
-
- constructor(gl: WebGLRenderingContext, shader: Shader, planets: Point[], bbox: BBox) {
- this.vor = new Voronoi();
- this.planets = planets;
-
- const ib = new IndexBuffer(gl, []);
- const vb = new VertexBuffer(gl, []);
-
- const layout = new VertexBufferLayout();
- layout.push(gl.FLOAT, 2, 4, "a_pos");
- layout.push(gl.FLOAT, 2, 4, "a_center");
- layout.push(gl.FLOAT, 1, 4, "a_own");
- layout.push(gl.FLOAT, 1, 4, "a_intensity");
-
- const vao = new VertexArray();
- vao.addBuffer(vb, layout);
-
- this.inner = new DefaultRenderable(ib, vao, shader, [], {});
-
- this.resize(gl, bbox);
- }
-
- getRenderable(): DefaultRenderable {
- return this.inner;
- }
-
- resize(gl: WebGLRenderingContext, bbox: BBox) {
- const start = new Date().getTime();
-
- // This voronoi sorts the planets, then owners don't align anymore
- const own_map = {};
- this.planets.forEach((p, i) => own_map[to_key(p)] = i);
-
- const vor = this.vor.compute(this.planets, bbox);
-
- const attrs = [];
- const ids = [];
-
- let vertCount = 0;
-
- for (let i = 0; i < vor.cells.length; i++) {
- const cell = vor.cells[i];
- const planetId = own_map[to_key(cell.site)];
- const point_map = build_point_map(cell.halfedges);
-
- const centerId = vertCount++;
-
- attrs.push(cell.site.x, cell.site.y);
- attrs.push(cell.site.x, cell.site.y);
- attrs.push(planetId);
- attrs.push(1);
-
- const dist_mean = cell.halfedges.map(e => {
- const start = e.getStartpoint();
- const end = e.getEndpoint();
- return dist(cell.site, start, true) + dist(cell.site, { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 }, true)
- }).reduce((a, b) => a + b, 0) / cell.halfedges.length / 2;
- const round_fn = get_round_fn(dist_mean);
-
- for (let edge of cell.halfedges) {
- let start = point_map(edge.getStartpoint());
- let end = point_map(edge.getEndpoint());
- let center = { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 };
-
- if (to_key(start) == to_key(end)) continue;
-
- start = round_point(cell.site, start, round_fn);
- center = round_point(cell.site, center, round_fn);
- end = round_point(cell.site, end, round_fn);
-
- ids.push(centerId);
- ids.push(vertCount++);
- attrs.push(start.x, start.y);
- attrs.push(cell.site.x, cell.site.y);
- attrs.push(planetId);
- attrs.push(0);
-
- ids.push(vertCount++);
- attrs.push(center.x, center.y);
- attrs.push(cell.site.x, cell.site.y);
- attrs.push(planetId);
- attrs.push(0);
-
- ids.push(centerId);
- ids.push(vertCount - 1);
-
- ids.push(vertCount++);
- attrs.push(end.x, end.y);
- attrs.push(cell.site.x, cell.site.y);
- attrs.push(planetId);
- attrs.push(0);
- }
- }
-
- this.inner.updateIndexBuffer(gl, ids);
- this.inner.updateVAOBuffer(gl, 0, attrs);
-
- console.log(`Vor things took ${new Date().getTime() - start} ms!`)
- }
-}
-
-export default VoronoiBuilder; \ No newline at end of file