仮想計算機構

IT業界と無縁な派遣社員のブログ

Beautiful Trigonometryが美しいので再現してみた

↓の動画が面白かったので自分で実装しました。

↓ここで見れます。
http://riverta.net/gallery/trigonometry/beautiful_trigonometry/main.html

コードは以下の通りです。

<html>
    <body>
        <script type="text/javascript" src="trigonometry.js"></script>
    </body>
</html>

const WIDTH = 500;
const HEIGHT = 500;

const canvas = document.createElement('canvas');
canvas.width = WIDTH;
canvas.height = HEIGHT;

const context = canvas.getContext('2d');

document.body.appendChild(canvas);

const CENTER_X = WIDTH/2;
const CENTER_Y = HEIGHT/2;
const RADIUS = 200; 

const NUM_CIRCLES = 12;
const T_MAX = 300;

class Circle{
    constructor(theta, phi, radius, color){
        this.theta = theta; 
        this.phi = phi; 
        this.radius = radius; 
        this.color = color;
        this.t = 0;
    }
    update(){
        this.theta += 2 * Math.PI / T_MAX;
        this.t += 1;
        if(this.t >= T_MAX){
            this.t = 0;
        }
    }
    render(context){
        context.beginPath();
        context.fillStyle = this.color;
        let x = CENTER_X + RADIUS * Math.cos(this.theta) * Math.cos(this.phi);
        let y = CENTER_Y + RADIUS * Math.cos(this.theta) * Math.sin(this.phi);
        context.arc(x, y, this.radius, 0, 2*Math.PI);
        context.fill();
    }
}
function draw_line(theta){
    context.beginPath () ;

    let x0 = CENTER_X + RADIUS * Math.cos(theta);
    let y0 = CENTER_Y + RADIUS * Math.sin(theta);
    context.moveTo(x0, y0) ;

    let x1 = CENTER_X - RADIUS * Math.cos(theta);
    let y1 = CENTER_Y - RADIUS * Math.sin(theta);
    context.lineTo(x1, y1)
    context.strokeStyle = "gray";
    context.lineWidth = 1;
    context.stroke() ;
}

const objects = [];
const dr = 2 * Math.PI / NUM_CIRCLES;
for(let i=0;i<NUM_CIRCLES;i++){
    let theta = i * dr / 2;
    let phi = i * dr / 2;
    objects.push(new Circle(theta, phi, 5, "black"));
}
objects[0].color = "red";
count = 0;
function loop(timestamp) {
  context.clearRect(0, 0, WIDTH, HEIGHT);
  for(let i=0;i<NUM_CIRCLES;i++){
    draw_line(i * dr / 2);
  }
  objects.forEach((obj) => obj.render(context));
  objects.forEach((obj) => obj.update());

  window.requestAnimationFrame((ts) => loop(ts));
}

window.requestAnimationFrame((ts) => loop(ts));