Nearest neighbor moiré 🧑‍🤝‍🧑

Connecting nearest neighbors of two overlayed grids, square and triangular using some parameters as to what to connect.
Concept: reddit.com/r/generat…generative_patterns/

Nearest neighbor moiré 🧑‍🤝‍🧑 (variation)

Log in to post a comment.

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

const distancePosition = 1; //min=0 max=30 step=1
const distanceThreshold = 1.2; //min=.5 max=3 step=.05
const distanceN = 2; //min=1 max=30 step=1
const distanceMode = 0; //0 = distance smaller than value at position times threshold, 1 just take first distanceN points
const squareSize = 13; //min=5 max=40 step=.5
const triangleSize = 10; //min=5 max=40 step=.5
const squareRotation = 0; //min=0 max=360 step=.1
const triangleRotation = 0; //min=0 max=360 step=.1
const squareOffsetX = 0; //min=-30 max=30 step=1
const triangleOffsetX = 0; //min=-30 max=30 step=1
const preventSmall = 1; //min=0 max=1 step=1 (No, Yes)

const grids = [
    [[squareSize, 0], [0, squareSize], rot2(2 * Math.PI * squareRotation / 360), squareOffsetX],
    [trans2(rot2(-Math.PI / 6), [triangleSize, 0]), [0, triangleSize], rot2(2 * Math.PI * triangleRotation / 360), triangleOffsetX]
];

const lim = 1.2 * 2**.5 * 100;

const points = [];

for(const grid of grids) {
    for(let x = -100; x < 100; x++) {
        for(let y = -100; y < 100; y++) {
            const pt = trans2(grid[2], add2([grid[3], 0], add2(scale2(grid[0], x), scale2(grid[1], y))));
            if(-lim < pt[0] && pt[0] < lim && -lim < pt[1] && pt[1] < lim) {
                points.push([points.length, pt]);
            }
        }
    }
}

// Global code will be evaluated once.
const turtle = new Turtle();

const drawn = [];
// The walk function will be called until it returns false.
function walk(i) {
    const closest = points.filter(pt => i != pt[0]).map(pt => [...pt, lenSq2(sub2(pt[1], points[i][1]))]);
    closest.sort((a,b) => a[2] < b[2]? -1: 1);

    for(let j = 0; (
        (distanceMode == 0 && closest[j][2] <= closest[distancePosition][2] * distanceThreshold) ||
        (distanceMode == 1 && j < distanceN)
    ) && j < closest.length - 1; j++) {
        const key = i < closest[j][0]? i + '_' + closest[j][0]: closest[j][0] + '_' + i;

        if(drawn[key] === undefined) {
            if(closest[j][2] >= preventSmall / 2) {
                turtle.jump(points[i][1]);
                turtle.goto(closest[j][1]);
            }
            drawn[key] = true;
        }
    }

    return i < points.length - 1;
}

////////////////////////////////////////////////////////////////
// 2D Vector Math utility code - Created by several Turtletoy users
////////////////////////////////////////////////////////////////
function add2(a, b) { return [a[0]+b[0], a[1]+b[1]]; }
function sub2(a, b) { return [a[0]-b[0], a[1]-b[1]]; }
function scale2(a, s) { return [a[0]*s, a[1]*s]; }
function lenSq2(a) { return a[0]**2+a[1]**2; }
function rot2(a) { return [Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a)]; }
function trans2(m, a) { return [m[0]*a[0]+m[2]*a[1], m[1]*a[0]+m[3]*a[1]]; } //Matrix(2x1) x Matrix(2x2)