ショートストーリー:「イオンの流れ、未来を描く」
東京、立川の静かなオフィスビルの一角。プログラマの佐藤ケンは、ディスプレイに映し出された複雑な数式とコードの海に没頭していた。彼が今取り組んでいるのは、自ら開発中の「イオンエンジンシミュレータ」の最終デバッグ作業。数ヶ月にわたる努力が結実する瞬間が近づいていた。
ケンは子供の頃から宇宙に憧れを抱いていた。特に、未来の宇宙探査を支えるであろうイオンエンジンに興味を持っていた。推力が弱いが、長時間の運転が可能なこの電気推進システムは、彼の頭の中で次世代の航行を実現する象徴だった。原子力バッテリーを使用して強大な大電力を供給することで比類なき大推力を生成する次世代型のイオンエンジン構想。今、彼は自らの手でそのシミュレーションを作り出し、未来の探査機を設計者たちに提供しようとしていたのだ。
コードの中で、ケンはイオン粒子の挙動をパーティクルとして描画し、流出速度によって色が変わる仕組みを実装していた。シミュレーション画面には、小さなイオン粒子が画面を飛び交い、速度が速いほど赤く、遅いほど青く輝く。彼はスライダーで放電容量と電力量を調整できるようにし、実際の宇宙探査機のエンジンのように、どのように推力が変化するかを可視化していた。
「よし、これで完了だ…」 最大の放電容量と電力量。
彼は一度深呼吸をして、スライダーを最大まで引き上げた。画面上では、エンジンから放たれたパーティクルが猛スピードで放射し、炎のように赤く輝いた。推力が急上昇し、まるで目の前のシミュレーションが本物の宇宙を切り開くエンジンのように動いている。速度が増すにつれ、イオンの色も変わり、冷たく青白い光を放つ低速の粒子は、やがて赤熱するかのような勢いで飛び出していく。
ケンは画面を見つめながら、過去を思い出していた。かつて彼は大学の宇宙物理学の授業で教授から「イオンエンジンの実用化は遠い未来の話だ」と聞かされたことがあった。しかし、その時から彼はこう思っていた――「その未来を自分の手で近づけてやる」と。
数年間のプログラミング経験を積んで、今この瞬間、彼はその夢に一歩近づいていた。彼のシミュレータは、単なるデモではなく、実際のイオンエンジン設計の一端を担う技術に成り得るものだった。
「これで宇宙へ行ける…いや、まだまだ始まりだ。」
画面に描かれる無数の粒子たちは、まるでケンの心に抱く希望のごとく、さまざまな色に輝きながら宇宙へと飛び出していく。これからも彼は、このシミュレータを改良し、さらに多くの要素を組み込むつもりだ。宇宙は広い。夢はまだ終わらない。
ケンはふと、窓の外を見上げた。東京の夜空には無数の星々がきらめいていた。その向こうには、いつか彼がこの手で到達する未来の宇宙が広がっている。
「さあ、次は現実のエンジンだ。」そう呟き、彼は新しいコードを書き始めた。
<!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;
}
canvas {
border: 1px solid black;
margin-top: 20px;
}
.controls {
margin-top: 20px;
}
</style>
</head>
<body>
<h1>イオンエンジン パーティクル シミュレーション</h1>
<canvas id="simulationCanvas" width="500" height="300"></canvas>
<div class="controls">
<label for="power">電力量: </label>
<input type="range" id="power" min="1" max="500" value="50">
<span id="powerValue">50</span> W
<br><br>
<label for="capacity">放電容量: </label>
<input type="range" id="capacity" min="1" max="500" value="50">
<span id="capacityValue">50</span> C
</div>
<script>
const canvas = document.getElementById('simulationCanvas');
const ctx = canvas.getContext('2d');
// スライダー要素
const powerSlider = document.getElementById('power');
const capacitySlider = document.getElementById('capacity');
const powerValue = document.getElementById('powerValue');
const capacityValue = document.getElementById('capacityValue');
// パーティクルの初期設定
let particles = [];
const numParticles = 1000;
let power = 50; // 電力量
let capacity = 50; // 放電容量
let ionSpeed = 0; // イオンの流出速度
// スライダーの変化を検知
powerSlider.addEventListener('input', (e) => {
power = parseInt(e.target.value);
powerValue.textContent = power;
});
capacitySlider.addEventListener('input', (e) => {
capacity = parseInt(e.target.value);
capacityValue.textContent = capacity;
});
// イオンの色を流出速度に応じて変える関数
function getIonColor(speed) {
const red = Math.min(255, speed * 5);
const blue = 255 - red;
return `rgb(${red}, 0, ${blue})`;
}
// パーティクルクラス
class Particle {
constructor() {
this.reset();
}
// パーティクルの位置や速度をリセット
reset() {
this.x = 250; // エンジンの中心位置
this.y = 150;
this.speed = Math.random() * ionSpeed + 1;
this.angle = Math.random() * Math.PI * 2;
this.life = 100; // パーティクルの寿命
this.color = getIonColor(this.speed);
}
// パーティクルの更新
update() {
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
this.life--;
if (this.life <= 0) {
this.reset(); // 寿命が尽きたらリセット
}
}
// パーティクルの描画
draw(ctx) {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
ctx.fill();
}
}
// パーティクルを初期化
for (let i = 0; i < numParticles; i++) {
particles.push(new Particle());
}
// アニメーション描画関数
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // キャンバスをクリア
// イオンエンジンの中心部を描画
ctx.fillStyle = 'gray';
ctx.fillRect(230, 130, 40, 40);
// イオンの流出速度を計算
ionSpeed = (power * capacity) / 1000; // 簡略化したモデル
// パーティクルを更新・描画
for (let i = 0; i < particles.length; i++) {
particles[i].update();
particles[i].draw(ctx);
}
// 次のフレームをリクエスト
requestAnimationFrame(draw);
}
// 初回描画
draw();
</script>
</body>
</html>