宇宙船の惑星スイングバイ
シュミレーション
DeepSeekでjavascriptでシュミレーション作成
シュミレーションHTML(swinby.html)
スイングバイシュミレーション
スマホはswingbyiphoneから開いてください
DeepSeekを使ったシュミレーションのプログラムです。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>宇宙船スイングバイシミュレーション</title> <style> canvas { border: 1px solid black; display: block; margin: 0 auto; } #controls { text-align: center; margin-top: 10px; } button { padding: 10px 20px; font-size: 16px; } label { font-size: 16px; margin-right: 10px; } input[type="range"] { width: 200px; } </style> </head> <body> <canvas id="spaceCanvas" width="800" height="600"></canvas> <div id="controls"> <button id="startButton">スタート</button> <button id="stopButton">ストップ</button> <button id="resetButton">リセット</button> <div> <label for="speedSlider">宇宙船の速度:</label> <input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="2"> <span id="speedValue">2</span> </div> <div> <label>実際の速度:</label> <span id="actualSpeedValue">0</span> </div> </div> <script> const canvas = document.getElementById('spaceCanvas'); const ctx = canvas.getContext('2d'); // 中心の星(仮想的な中心点)の設定 const centerStar = { x: canvas.width / 2, y: canvas.height / 2, radius: 20, mass: 100000 }; // 惑星の初期設定 const planet = { x: canvas.width / 2 + 200, // 初期位置を中心から離す y: canvas.height / 2, radius: 20, // 惑星のサイズを小さくする mass: 10000, orbitRadius: 200, // 公転半径 orbitSpeed: 0.02, // 公転速度(ラジアン/フレーム) angle: 0 // 公転角度 }; // 宇宙船の初期設定 const spaceship = { x: 100, y: 100, radius: 5, vx: 2, // 初期速度 vy: 0, mass: 1 }; const G = 0.1; // 重力定数(シミュレーション用) let animationId = null; // アニメーションIDを保持する変数 let isRunning = false; // アニメーションの実行状態を管理するフラグ // 速度スライダーの要素を取得 const speedSlider = document.getElementById('speedSlider'); const speedValue = document.getElementById('speedValue'); const actualSpeedValue = document.getElementById('actualSpeedValue'); // スライダーの値が変更されたときのイベントリスナー speedSlider.addEventListener('input', () => { const speed = parseFloat(speedSlider.value); spaceship.vx = speed; // 宇宙船の速度を更新 speedValue.textContent = speed; // 表示を更新 }); // 宇宙船をリセットする関数 function resetSpaceship() { spaceship.x = 100; spaceship.y = 100; spaceship.vx = parseFloat(speedSlider.value); spaceship.vy = 0; } // 宇宙船の速度を計算する関数 function calculateSpeed() { return Math.sqrt(spaceship.vx * spaceship.vx + spaceship.vy * spaceship.vy); } // 惑星の公転を更新する関数 function updatePlanetOrbit() { planet.angle += planet.orbitSpeed; // 公転角度を更新 planet.x = centerStar.x + Math.cos(planet.angle) * planet.orbitRadius; // X座標を更新 planet.y = centerStar.y + Math.sin(planet.angle) * planet.orbitRadius; // Y座標を更新 } // アニメーションの更新 function update() { // 惑星の公転を更新 updatePlanetOrbit(); // 惑星と宇宙船の距離を計算 const dx = planet.x - spaceship.x; const dy = planet.y - spaceship.y; const distance = Math.sqrt(dx * dx + dy * dy); // 重力による加速度を計算 const force = (G * planet.mass) / (distance * distance); const angle = Math.atan2(dy, dx); const ax = force * Math.cos(angle); const ay = force * Math.sin(angle); // 宇宙船の速度を更新 spaceship.vx += ax; spaceship.vy += ay; // 宇宙船の位置を更新 spaceship.x += spaceship.vx; spaceship.y += spaceship.vy; // 画面外に出た場合の処理 if (spaceship.x < 0 || spaceship.x > canvas.width || spaceship.y < 0 || spaceship.y > canvas.height) { resetSpaceship(); } // 実際の速度を表示 actualSpeedValue.textContent = calculateSpeed().toFixed(2); } // 描画関数 function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 中心の星を描画 ctx.beginPath(); ctx.arc(centerStar.x, centerStar.y, centerStar.radius, 0, Math.PI * 2); ctx.fillStyle = 'yellow'; ctx.fill(); // 惑星を描画 ctx.beginPath(); ctx.arc(planet.x, planet.y, planet.radius, 0, Math.PI * 2); ctx.fillStyle = 'blue'; ctx.fill(); // 宇宙船を描画 ctx.beginPath(); ctx.arc(spaceship.x, spaceship.y, spaceship.radius, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); } // アニメーションループ function animate() { update(); draw(); if (isRunning) { animationId = requestAnimationFrame(animate); } } // スタートボタンのイベントリスナー document.getElementById('startButton').addEventListener('click', () => { if (!isRunning) { isRunning = true; animate(); } }); // ストップボタンのイベントリスナー document.getElementById('stopButton').addEventListener('click', () => { if (isRunning) { isRunning = false; cancelAnimationFrame(animationId); } }); // リセットボタンのイベントリスナー document.getElementById('resetButton').addEventListener('click', () => { resetSpaceship(); isRunning = false; cancelAnimationFrame(animationId); draw(); // リセット後の状態を描画 actualSpeedValue.textContent = calculateSpeed().toFixed(2); // 速度を更新 }); // 初期描画 draw(); actualSpeedValue.textContent = calculateSpeed().toFixed(2); // 初期速度を表示 </script> </body> </html>
スマホ対応(ChatGDP)で作りました。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>宇宙船スイングバイシミュレーション</title> <style> canvas { border: 1px solid black; display: block; margin: 0 auto; max-width: 100%; height: auto; } #controls { text-align: center; margin-top: 10px; } button { padding: 10px 20px; font-size: 16px; margin: 5px; } label { font-size: 16px; margin-right: 10px; } input[type="range"] { width: 100%; max-width: 200px; } </style> </head> <body> <canvas id="spaceCanvas"></canvas> <div id="controls"> <button id="startButton">スタート</button> <button id="stopButton">ストップ</button> <button id="resetButton">リセット</button> <div> <label for="speedSlider">宇宙船の速度:</label> <input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="2"> <span id="speedValue">2</span> </div> <div> <label>実際の速度:</label> <span id="actualSpeedValue">0</span> </div> </div> <script> const canvas = document.getElementById('spaceCanvas'); const ctx = canvas.getContext('2d'); // 恒星 const centerStar = { x: 0, y: 0, radius: 20, mass: 100000 }; // 惑星 const planet = { x: 0, y: 0, radius: 15, mass: 10000, orbitRadius: 0, orbitSpeed: 0.02, angle: 0 }; // 宇宙船 const spaceship = { x: 100, y: 100, radius: 5, vx: 2, vy: 0, mass: 1 }; const G = 0.1; // 重力定数 let isRunning = false; let animationId = null; // キャンバスのリサイズ function resizeCanvas() { canvas.width = window.innerWidth * 0.9; canvas.height = window.innerHeight * 0.7; centerStar.x = canvas.width / 2; centerStar.y = canvas.height / 2; planet.orbitRadius = Math.min(canvas.width, canvas.height) * 0.3; draw(); } window.addEventListener('resize', resizeCanvas); resizeCanvas(); // 惑星の公転を更新 function updatePlanetOrbit() { planet.angle += planet.orbitSpeed; planet.x = centerStar.x + Math.cos(planet.angle) * planet.orbitRadius; planet.y = centerStar.y + Math.sin(planet.angle) * planet.orbitRadius; } // 宇宙船の速度を計算 function calculateSpeed() { return Math.sqrt(spaceship.vx ** 2 + spaceship.vy ** 2); } // 宇宙船のリセット function resetSpaceship() { spaceship.x = 100; spaceship.y = 100; spaceship.vx = parseFloat(speedSlider.value); spaceship.vy = 0; } // 物理計算 function update() { updatePlanetOrbit(); const dx = planet.x - spaceship.x; const dy = planet.y - spaceship.y; const distance = Math.sqrt(dx ** 2 + dy ** 2); // 重力の計算 if (distance > planet.radius) { const force = (G * planet.mass) / (distance ** 2); const angle = Math.atan2(dy, dx); const ax = force * Math.cos(angle); const ay = force * Math.sin(angle); spaceship.vx += ax; spaceship.vy += ay; } // 宇宙船の移動 spaceship.x += spaceship.vx; spaceship.y += spaceship.vy; // 画面外に出た場合の処理 if (spaceship.x < 0 || spaceship.x > canvas.width || spaceship.y < 0 || spaceship.y > canvas.height) { resetSpaceship(); } actualSpeedValue.textContent = calculateSpeed().toFixed(2); } // 描画 function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 恒星 ctx.beginPath(); ctx.arc(centerStar.x, centerStar.y, centerStar.radius, 0, Math.PI * 2); ctx.fillStyle = 'yellow'; ctx.fill(); // 惑星 ctx.beginPath(); ctx.arc(planet.x, planet.y, planet.radius, 0, Math.PI * 2); ctx.fillStyle = 'blue'; ctx.fill(); // 宇宙船 ctx.beginPath(); ctx.arc(spaceship.x, spaceship.y, spaceship.radius, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); } // アニメーションループ function animate() { update(); draw(); if (isRunning) { animationId = requestAnimationFrame(animate); } } // UIイベント document.getElementById('startButton').addEventListener('click', () => { if (!isRunning) { isRunning = true; animate(); } }); document.getElementById('stopButton').addEventListener('click', () => { isRunning = false; cancelAnimationFrame(animationId); }); document.getElementById('resetButton').addEventListener('click', () => { resetSpaceship(); isRunning = false; cancelAnimationFrame(animationId); draw(); actualSpeedValue.textContent = calculateSpeed().toFixed(2); }); document.getElementById('speedSlider').addEventListener('input', () => { spaceship.vx = parseFloat(speedSlider.value); speedValue.textContent = speedSlider.value; }); draw(); </script> </body> </html>
文字で読むよりシュミレーションで見る方がよくわかりますね。
チャットに「宇宙船が公転する惑星によるスイングバイのシュミレーションプログラムをJavascriptで作って。」と入力して作りました。
スタートボタンなど配置やスピードの変更などを追加しました。
AIは、全くエラー構文を作らずにプログラムを作っています。
ここまで、20分くらいでした。
ただDeepseekの回答が途切れることがありました。その都度、新規に始めて続けました。
チャットに入力する際、日本語は普通に使えますが漢字変換後の確定のためのエンターキーで送信されてしまうので注意が必要です。
スマホ版はDeepseekではうまくできませんでした。そこでChatGDPで作ってもらいました。作成速度は同じくらいですが、安定していました。