diff --git a/artworld/index.js b/artworld/index.js index cefb701..c1e4cf4 100644 --- a/artworld/index.js +++ b/artworld/index.js @@ -1,6 +1,6 @@ export { artworld } from "./world.js"; export { Color, Pico8 } from "./color.js"; export { Vector2, degToRad, radToDeg } from "./math.js"; -export { Line, Rect, Circle, Arc } from "./shapes.js"; +export { Line, Rect, Circle, Arc, Polygon } from "./shapes.js"; export { Group } from "./drawable.js"; export { Random } from "./random.js"; diff --git a/artworld/math.js b/artworld/math.js index 52553b0..8ea4263 100644 --- a/artworld/math.js +++ b/artworld/math.js @@ -27,6 +27,12 @@ export class Vector2 { return new Vector2(s * this.x, s * this.y); } + distance(other) { + return Math.sqrt( + Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2), + ); + } + static random(x, y) { let theta = Random.radians(); // if neither specified, use (1, 1) diff --git a/artworld/shapes.js b/artworld/shapes.js index 4021fa1..e57dda4 100644 --- a/artworld/shapes.js +++ b/artworld/shapes.js @@ -158,3 +158,67 @@ export class Rect extends Drawable { // ); // } } + +export class Polygon extends Drawable { + constructor(parent) { + super(parent); + this._points = []; + } + + random(n = 7) { + super.random(); + let points = []; + let i; + // generate points + for (i = 0; i < n; i++) { + points.push( + new Vector2(Random.between(50, 200), Random.between(50, 200)), + ); + } + // sort points by distance for mostly convex (but not always) polygons + this._points.push(points.shift()); // take first element + while (points.length) { + let closestIdx = 0; + let closestDist = 999999999; + let dist; + for (let j = 0; j < points.length; j++) { + dist = this._points[this._points.length - 1].distance(points[j]); + if (dist < closestDist) { + closestDist = dist; + closestIdx = j; + } + } + this._points.push(points[closestIdx]); + points.splice(closestIdx, 1); + } + + return this; + } + + copy(overrides) { + return makeCopy(Polygon, this, overrides); + } + + draw() { + artworld.prepareDraw(this); + artworld.drawPolygon(this.worldPos, this._points); + } + + point(vector, to_modify = null) { + if (to_modify !== null) { + self._points[to_modify] = vector; + } else { + self._points.push(point); + } + return self; + } + // TODO + // contains(x, y) { + // return ( + // x > this.x && + // x < this.x + this._width && + // y > this.y && + // y < this.pos.y + this._height + // ); + // } +} diff --git a/artworld/world.js b/artworld/world.js index 24eefff..912f57a 100644 --- a/artworld/world.js +++ b/artworld/world.js @@ -95,6 +95,17 @@ export class World { if (this._stroke) this.ctx.stroke(); if (this._fill) this.ctx.fill(); } + + drawPolygon(center, points) { + this.ctx.beginPath(); + this.ctx.moveTo(center.x + points[0].x, center.y + points[0].y); + for (let i = 1; i < points.length; i++) { + this.ctx.lineTo(center.x + points[i].x, center.y + points[i].y); + } + this.ctx.lineTo(center.x + points[0].x, center.y + points[0].y); + if (this._stroke) this.ctx.stroke(); + if (this._fill) this.ctx.fill(); + } } // singleton (for now) diff --git a/examples/polygons.html b/examples/polygons.html new file mode 100644 index 0000000..21d1321 --- /dev/null +++ b/examples/polygons.html @@ -0,0 +1,29 @@ + + + + + + +