Log in to post a comment.

// Thomas Attractor - Labyrinthine Version
// dx/dt = -beta*x + sin(y)
// dy/dt = -beta*y + sin(z)
// dz/dt = -beta*z + sin(x)

const randomize_inputs = 1; // min=0, max=1, step=1 (Use Input, Randomize)
const steps = 50000; // min=5000, max=150000, step=5000

// --- ADJUSTABLE PARAMETERS ---
const beta_param = 0.16; // min=0.05, max=0.4, step=0.01 (Dissipation)
const scale = 35;        // min=10, max=100, step=1
const opacity = 0.4;     // min=0.1, max=1.0, step=0.05
const dt = 0.15;         // min=0.05, max=0.5, step=0.01 (Resolution)

let beta = beta_param;

// Initial State (Standard starting point)
let x = 0.1;
let y = 0.0;
let z = 0.0;

if (randomize_inputs == 0) {
    beta = 0.15 + Math.random() * 0.1;
}

Canvas.setpenopacity(opacity);
const turtle = new Turtle();
turtle.penup();

// 3D to 2D Projection (Isometric style to see the grid)
function project(currX, currY, currZ) {
    let screenX = (currX - currY) * Math.cos(0.7) * scale;
    let screenY = (currZ - (currX + currY) * 0.5) * scale;
    return [screenX, screenY];
}

let startPos = project(x, y, z);
turtle.jump(startPos[0], startPos[1]);
turtle.pendown();

function walk(i) {
    // 1. Thomas Equations from your image
    let dx = -beta * x + Math.sin(y);
    let dy = -beta * y + Math.sin(z);
    let dz = -beta * z + Math.sin(x);

    // 2. Integration
    x += dx * dt;
    y += dy * dt;
    z += dz * dt;

    // 3. Draw
    let pos = project(x, y, z);
    
    // Safety check
    if (isNaN(x) || Math.abs(x) > 1000) return false;

    turtle.goto(pos[0], pos[1]);

    return i < steps;
}