前回のスピログラフ改良版です。余計なラインが出ないようにしてみました。
■スピログラフのパラメータ
外側の固定円(半径 R)
内側の回転円(半径 r)
描画点の距離 d(内円の中心からの距離)
ステップ数 s(1ユニットのプロット数)
角度 θ(回転角)
■スピログラフの方程式
スピログラフの曲線 (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;
            background-color: #333;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 1px solid #000;
            background-color: #000;
            margin-top: 10px;
        }
        input { 
            margin: 5px; 
            text-align: right; 
            width: 40px; 
        }
        .controls {
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <font color="white">
    <h2>スピログラフ描画</h2>
    </font>
    <div class="controls">
        <font color="white">
        <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>ステップ数: <input type="number" 
            id="steps" value="200"></label>
        <label>回転数: <input type="number" 
            id="rotations" value="10"></label>
        <button onclick="drawSpirograph()">描画</button>
        </font>
    </div>
    <canvas id="spiroCanvas" width="550" height="550"></canvas>
    <script>
        function drawSpirograph() {
            // ユーザー入力を取得
            let R = parseFloat(document.getElementById('R').value);
            let r = parseFloat(document.getElementById('r').value);
            let d = parseFloat(document.getElementById('d').value);
            let steps = parseInt(document.getElementById('steps').
                value, 10);
            let rotations = parseInt(document.getElementById('rotations').
                value, 10);
            // Canvas の設定
            let canvas = document.getElementById('spiroCanvas');
            let ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.strokeStyle = 'yellow';
            ctx.lineWidth = 2;
            // 中心座標
            let centerX = canvas.width / 2;
            let centerY = canvas.height / 2;
            // スピログラフの描画
            ctx.beginPath();
            for (let i = 0; i <= steps * rotations; i++) {
                let theta = (Math.PI * 2 * i) / steps;
                let x = (R - r) * Math.cos(theta) + 
                    d * Math.cos(((R - r) / r) * theta);
                let y = (R - r) * Math.sin(theta) - 
                    d * Math.sin(((R - r) / r) * theta);
                if (i === 0) {
                    ctx.moveTo(centerX + x, centerY + y);
                } else {
                    ctx.lineTo(centerX + x, centerY + y);
                }
            }
            ctx.stroke();
        }
        // 初回描画
        drawSpirograph();
    </script>
</body>
</html>
<!-- index.html -->
実行直後の状態です。
パラメーター変更例(その1)
パラメーター変更例(その2)
パラメーター変更例(その3)





 
 
 

 
