git @ Cat's Eye Technologies Gridoggerel / master src / gridoggerel.js
master

Tree @master (Download .tar.gz)

gridoggerel.js @masterraw · history · blame

// SPDX-FileCopyrightText: Chris Pressey, the creator of this work, has dedicated it to the public domain.
// For more information, please refer to <https://unlicense.org/>
// SPDX-License-Identifier: Unlicense


CELL_WIDTH = 20;
CELL_HEIGHT = 20;


Gridoggerel = function() {
    this.init = function(cfg) {
        this.canvas = cfg.canvas;
        this.ctx = this.canvas.getContext('2d');
        this.gridHeight = 20;
        this.gridWidth = 20;
        this.numPoints = 50;
        this.lineWidth = 4;
        this.reset();
    };

    this.reset = function() {
        this.points = [];
        var i;
        for (i = 0; i < this.numPoints; i++) {
            var pt = this.randPoint();
            if (pt !== null) {
                this.points.push(this.randPoint());
            }
        }
        this.draw();
    };

    this.draw = function() {
        this.ctx.fillStyle = '#8080ff';
        this.ctx.strokeStyle = 'black';
        this.ctx.lineWidth = this.lineWidth;
        this.ctx.lineCap = 'round';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        for (const point of this.points) {
            var connected = false;
            for (const other of this.points) {
                // Don't compare to self
                if (point[0] === other[0] && point[1] === other[1]) {
                    continue;
                }
                // If in the same row, or in the same column - connect!
                if (point[0] === other[0] || point[1] === other[1]) {
                    this.connectPoints(point, other);
                    connected = true;
                }
            }
            if (!connected) {
                let nearestPoint = null;
                let nearestDist = null;
                for (const other of this.points) {
                    // Don't compare to self
                    if (point[0] === other[0] && point[1] === other[1]) {
                        continue;
                    }
                    let dx = point[0] - other[0];
                    let dy = point[1] - other[1];
                    let dist = dx * dx + dy * dy;
                    if (nearestDist === null || dist < nearestDist) {
                        nearestDist = dist;
                        nearestPoint = other;
                    }
                }
                if (nearestPoint !== null) {
                    this.connectPoints(point, nearestPoint);
                } else {
                    console.log("This can't be happening");
                }
            }
        }
    };

    this.randPoint = function() {
        let attempts = 0;
        let newPt = null;
        let alreadyExists = false;
        while (attempts < 100) {
            attempts += 1;
            newPt = [
                Math.trunc(Math.random() * this.gridWidth),
                Math.trunc(Math.random() * this.gridHeight)
            ];
            alreadyExists = false;
            for (const point of this.points) {
                if (point[0] === newPt[0] && point[1] === newPt[1]) {
                    alreadyExists = true;
                    break;
                }
            }
            if (!alreadyExists) {
                return newPt;
            }
        }
        return null;
    };

    this.connectPoints = function(pointA, pointB) {
        this.ctx.beginPath();
        var xOffs = CELL_WIDTH / 2;
        var yOffs = CELL_HEIGHT / 2;
        this.ctx.moveTo(pointA[0] * CELL_WIDTH + xOffs, pointA[1] * CELL_HEIGHT + yOffs);
        this.ctx.lineTo(pointB[0] * CELL_WIDTH + xOffs, pointB[1] * CELL_HEIGHT + yOffs);
        this.ctx.stroke();
    };
}