木曜日, 4月 17, 2025

Let's start JavaScript 62 
HTML上でスピログラフを描画

HTML上でスピログラフを描画させてみました。

■スピログラフのパラメータ
外側の固定円(半径 R)
内側の回転円(半径 r)
描画点の距離 d(内円の中心からの距離)
角度 θ(回転角)

■スピログラフの方程式
スピログラフの曲線 (x, y) は、以下のパラメータ方程式で表されます。

基本形(ハイポサイクロイド)
x(θ)=(R-r)cos(θ)+d cos(((R-r)r)θ)
y(θ)=(R-r)sin(θ)-d sin(((R-r)r)θ)

ここで:

θ は回転角(0 から 2π × ループ回数 まで変化)
(R - r) の比が整数であれば閉じた軌跡になる

<!-- index.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport"
        content="width=device-width, initial-scale=1.0">
<title>スピログラフ描画</title>
<style>
body { text-align: center; font-family: Arial, sans-serif; }
canvas { border: 1px solid black; margin-top: 10px;
            background-color: black;}
input { margin: 5px; text-align: right; width: 40px; }
</style>
</head>
<body bgcolor="#333">
<font color="white">
<h2>スピログラフ描画</h2>
<label>外円 R: <input type="number"
        id="R" value="150"></label>
<label>内円 r: <input type="number"
        id="r" value="70"></label>
<label>距離 d: <input type="number"
        id="d" value="100"></label>
<label>回転数 loops: <input type="number"
        id="loops" value="10"></label>
</font>
<button onclick="drawSpirograph()">描画</button>
<br>
<canvas id="canvas" width="550" height="550"></canvas>

<script>
function drawSpirograph() {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
            // 画面クリア
ctx.clearRect(0, 0, canvas.width, canvas.height);

// ユーザー入力取得
let R = parseFloat(document.getElementById("R").value);
let r = parseFloat(document.getElementById("r").value);
let d = parseFloat(document.getElementById("d").value);
let loops = parseInt(document.getElementById("loops").
                value, 10);
let step = 0.1; // 角度のステップ(小さいほど滑らか)

let centerX = canvas.width / 2;
let centerY = canvas.height / 2;
let t = 0;
let totalSteps = Math.PI * 2 * loops;
let points = [];

// 計算して座標を取得
while (t < totalSteps) {
let x = (R - r) * Math.cos(t) + d * Math.cos((R - r) / r * t);
let y = (R - r) * Math.sin(t) - d * Math.sin((R - r) / r * t);
points.push({ x: centerX + x, y: centerY + y });
t += step;
}

// スピログラフを描画
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.closePath();
ctx.strokeStyle = "yellow";
ctx.lineWidth = 2;
ctx.stroke();
}

// 初回の描画
drawSpirograph();
</script>
</body>
</html>
<!-- index.html -->

実行直後の状態です。赤枠で囲んだ部分の処理は今後の課題です(>_<)

パラメーター変更例(その1)

パラメーター変更例(その2)
線がブレているように見えますね(>_<)

パラメーター変更例(その3)