A pendant fit for a Titan.
Log in to post a comment.
// Forked from "Multiball Exhibition" by maraz // https://turtletoy.net/turtle/51730d3ea5 const quality = 2.25; // min=0.15, max=9, step=0.15 const letterbox = 0; // min=0.0, max=1.0, step=0.01 const canvasSize = 1024; const coordSize = 200; const step = coordSize/canvasSize/quality; const halfCanvas = canvasSize/2; const halfCoord = coordSize/2; const topCoord = -halfCoord+letterbox*halfCoord; const bottomCoord = halfCoord - letterbox*halfCoord; const nBalls = 23; const ballMinSize = 1; const ballMaxSize = 40; const ballYGap = 5; const ballsY = -80.5; const ballsX = 61; const ballsMinDX = -60; const ballsMaxDX = 15; const ballDarkest = 0.6; const ballLightest = 1; const ballSeries = (n, xFn, yFn, sizeFn, darknessFn) => { let balls = [] for (let i = 0; i <= n; i++) { balls.push({ i, size: sizeFn(i), xPos: xFn(i), yPos: yFn(i), darkness: darknessFn(i), }) } return balls.reverse(); } const balls = ballSeries(nBalls, (i) => ballsX +((i+1)%2) * i**2.7/nBalls/64*ballsMinDX +(i%2) * i**2.7/nBalls/64*ballsMaxDX, (i) => ballsY +((i+1)%2) * (Math.sin(Math.PI*0.76+Math.PI*i**2/nBalls*0.0102)*i**2/nBalls*2)*ballYGap +(i%2) * (Math.sin(Math.PI*0.29+Math.PI*i**2/nBalls*0.0102)*i**2/nBalls*2)*ballYGap, (i) => ballMinSize+((1+i)/nBalls)**2*(ballMaxSize-ballMinSize), (i) => ballLightest+(i)/nBalls*(ballDarkest-ballLightest), ) Turtle.prototype.step = function(draw = false) { draw && this.pendown(); this.forward(step); draw && this.penup(); } // This gives us antialiasing for quality > 1. Canvas.setpenopacity(-1+0.0875*(quality-1)); const turtle = new Turtle(); turtle.penup(); turtle.goto(-halfCoord, topCoord); turtle.seth(0); const getCirclePos = (x, y) => Math.sqrt(x*x+y*y); const checkCircle = (circle, x, y) => { const ax = Math.abs(x); const ay = Math.abs(y); if (ay < circle.size && ax < circle.size) { const circlePos = getCirclePos(x, y); if (circlePos < circle.size) { return circlePos; } } return false; } const checkBalls = (x, y) => { for (const ball of balls) { const _x = x - ball.xPos; const _y = y - ball.yPos; const ballPos = checkCircle(ball, _x, _y); if (ballPos != false) { return { ...ball, x: _x, y: _y, ballPos }; } } return false; } const ballStep = (_ball) => { return ( (Math.round(7*Math.random()) == 0) || Math.round(1.25-(Math.random()*(-_ball.x/(_ball.size))))>1 || Math.round(0.875-(Math.random()*(_ball.x/(_ball.size))))>1 || Math.round(1.25-(Math.random()*(_ball.ballPos/(_ball.size))))<1 ) && Math.round(_ball.darkness * Math.random())==0 } const backgroundStep = (_x, _y, xoff, yoff, xt, yt, dt) => { const x = _x + xoff; const y = _y + yoff; return ( (Math.round(7*Math.random()) == 0) || Math.round( Math.abs(-0.25 + (halfCoord/2+y)/halfCoord*8 *Math.sin(xt*(100+y) + Math.cos(dt*(100+y)) + Math.cos(dt*(100+x))) *Math.cos(yt*(100+x) + Math.sin(dt*(100+x)) + Math.sin(dt*(100+y) + Math.cos(1.92*dt*(100+y)))) ) * Math.random()/0.25*Math.abs(y)/halfCoord )==3 ); } function drawBackground(x, y) { turtle.step(backgroundStep(x, y, 4836, -174, 0.045, 0.0063, 0.029)); } function drawBall(_ball) { turtle.step(ballStep(_ball)); } const lineMultiplier = 1/quality; let stillMultiplying = 0; let yStep = step/lineMultiplier; function walk(i) { const x = turtle.x(); const y = turtle.y(); if (x > halfCoord) { if (quality < 1) { if (stillMultiplying >= lineMultiplier) { stillMultiplying = 0; } stillMultiplying = stillMultiplying + 1; turtle.goto(-halfCoord, y+yStep); } else { turtle.goto(-halfCoord, y+step); } return true; } const maybeBall = checkBalls(x, y-yStep*stillMultiplying); if (maybeBall) { drawBall(maybeBall); } else { drawBackground(x, y); } return y < bottomCoord; }