JSFiddle - React, Tailwind, and code Playground

by SwagColoredKitteh

HTML

<canvas id="canvas" width="480" height="480"></canvas>

TypeScript

const doc = {
	canvas: document.querySelector("#canvas")
};

const ctx = doc.canvas.getContext("2d");

class Vec2 {
	public x: number;
  public y: number;
  
	constructor(x: number, y: number) {
  	this.x = x;
    this.y = y;
    Object.freeze(this);
  }
  
  dot(other: Vec2): number {
  	return this.x * other.x + this.y * other.y;
  }
  
  cross(other: Vec2): number {
  	return this.x * other.y - this.y * other.x;
  }
  
  sub(other: Vec2): Vec2 {
  	return new Vec2(this.x - other.x, this.y - other.y);
  }
  
  perp(): Vec2 {
 		return new Vec2(-this.y, this.x);
  }
}

function vec2(x: number, y: number): Vec2 {
	return new Vec2(x, y);
}

enum Rot {
	CW,
  CCW,
  None
}

class Line {
	public start: Vec2;
  public end: Vec2;
  
  constructor(start: Vec2, end: Vec2) {
  	this.start = start;
    this.end = end;
    Object.freeze(this);
  }
  
  sideOf(p: Vec2): Rot {
  	const d = this.end.sub(this.start).cross(p.sub(this.start));
    if(d < 0) {return Rot.CCW;}
    if(d > 0) {return Rot.CW;}
    return Rot.None;
  }
  
  intersectionWith(other: Line): Vec2 {
  	// TODO: figure out how this works
  	const a = this.start.x * this.end.y - this.start.y * this.end.x;
    const b = other.start.x * other.end.y - other.start.y * other.end.x;
    const c = this.start.x - this.end.x;
    const d = other.start.x - other.end.x;
    const e = this.start.y - this.end.y;
    const f = other.start.y - other.end.y;
    const denom = c * f - e * d;
    if(denom !== 0) {
      const x = (a * d - c * b) / denom;
      const y = (a * f - e * b) / denom;
      return new Vec2(x, y);
    }
    else {
    	return null;
    }
  }
}

class Polygon {
	public vertices: Array<Vec2>;
  
  constructor(vertices: Array<Vec2>) {
  	// ASSUMPTION: polygon is CW
  	this.vertices = vertices;
  }
  
  *edges(): Iterator<Line> {
  	for(let i = 0; i < this.vertices.length; i++) {
    	yield new Line(this.vertices[i], this.vertices[(i + 1) % this.vertices.length]);
    }
  }
  
  trace(ctx) {
 ...