Blo4rp

quick scrawl

Log in to post a comment.

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

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

class Vec2 {
    constructor(x, y) {
        this.x = x
        this.y = y
    }

    rotate(angle) {
        return new Vec2(
            this.x * Math.cos(angle) - this.y * Math.sin(angle),
            this.x * Math.sin(angle) + this.y * Math.cos(angle)
        )
    }
    
    multn(n) {
        return new Vec2(this.x * n, this.y * n)
    }

    add(pt) {
        return new Vec2(this.x + pt.x, this.y + pt.y)
    }

    sub(pt) {
        return new Vec2(this.x - pt.x, this.y - pt.y)
    }
    
    index(size) {
        return Math.floor(this.x) + Math.floor(this.y) * size
    }

    equals(pt) {
        return this.x === pt.x && this.y === pt.y
    }
    
    distance(pt) {
        return Math.sqrt((this.x - pt.x) ** 2 + (this.y - pt.y) ** 2)
    }
    
    floor(pt) {
        return new Vec2(Math.floor(this.x), Math.floor(this.y))
    }

    addX(x) {
        return new Vec2(this.x + x, this.y)
    }

    addY(y) {
        return new Vec2(this.x, this.y + y)
    }    

    static lerp(a, b, fract) {
        return new Vec2(lerp(a.x, b.x, fract), lerp(a.y, b.y, fract))
    }
}


function clamp(v, min, max) {
    return Math.max(Math.min(v, max), min)
}

function lerp(a, b, fract) {
    return a + (b - a) * fract
}

function opSmoothUnion( d1, d2, k ) {
    
    let h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
    return lerp( d2, d1, h ) - k*h*(1.0-h); 
}

function opSubtraction( d1, d2 ) { return Math.max(d1,d2); }

function field(vv) {

    let core1 = new Vec2( -45, -45 );
    let core2 = new Vec2( 45, -45 );
    let core3 = new Vec2( -45, 45 );
    let core4 = new Vec2( 45, 45 );
    
    let merge = 110.0;
  
    let fl = opSmoothUnion(
            opSmoothUnion( vv.distance(core1), vv.distance(core2), merge ),
            opSmoothUnion( vv.distance(core3), vv.distance(core4), merge ),
            merge );
    
    return fl;
}

// The walk function will be called until it returns false.
function walk(i) {

    turtle.penup();

    let yoff = -canvas_size + (i * 0.1);
    
    let op = ( Math.sin(yoff * 0.9 ) + 1.0 ) * 0.5;
    let oppow = Math.pow(op , 14);

    for (let xi=0; xi<canvas_size * 2; xi++) {    
        
        let cp = new Vec2( -canvas_size + xi, yoff );
        let dst = field(cp);

    
        if ( cp.distance(new Vec2(0,0)) < (op * 45 ) + (oppow*5) )
        {
            continue;
        }

        turtle.goto(cp.x, cp.y);
        
        if ( op > 0.32 &&  dst < 12 + (oppow * 32) )
        {
            turtle.pendown();
        
            turtle.forward(1);
        
            turtle.penup();
        }
    }
/*
    if (i <= 10)    
    {
        let rad = 5;
        let ix = i * 0.1;
    turtle.penup();
    turtle.goto(0, 0 + ( -rad-ix) );
    turtle.pendown();
    turtle.circle(rad+ix, 360);
    turtle.penup();
    }*/
    
    return i < canvas_size * 20;
}