ジュリア集合をプロットし、その点に沿ってカメラが移動するアニメーションのゲームです。
コードをメモ帳などのテキストエディタに貼り付け、ファイルを「index.html」などの拡張子が.htmlのファイルとして保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Julia Set in 3D</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// シーン、カメラ、レンダラーの設定
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// ジュリア集合のパラメータ
const cRe = -0.7, cIm = 0.27015;
const maxIterations = 300;
const points = []; // 点の配列
const colors = []; // カラフルな色の配列
// ジュリア集合の点を生成
for (let x = -1.5; x <= 1.5; x += 0.01) {
for (let y = -1.5; y <= 1.5; y += 0.01) {
let zx = x;
let zy = y;
let i = 0;
while (zx * zx + zy * zy < 4 && i < maxIterations) {
let tmp = zx * zx - zy * zy + cRe;
zy = 2.0 * zx * zy + cIm;
zx = tmp;
i++;
}
if (i < maxIterations) {
const hue = (i / maxIterations);
const color = new THREE.Color("hsl(" + hue * 360 + ", 100%, 50%)");
points.push(new THREE.Vector3(zx, zy, i * 0.05));
colors.push(color);
}
}
}
// ジオメトリとマテリアルを作成し、点群を作成
const geometry = new THREE.BufferGeometry().setFromPoints(points);
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors.map(c => [c.r, c.g, c.b]).flat(), 3));
const material = new THREE.PointsMaterial({ vertexColors: true, size: 0.1 });
const juliaSet = new THREE.Points(geometry, material);
scene.add(juliaSet); // シーンに追加
// カメラの初期位置とアニメーションの設定
camera.position.set(0, 0, 5); // カメラの初期位置
const cameraSpeed = 0.02; // カメラの移動速度
// アニメーションループ
function animate() {
requestAnimationFrame(animate);
// ジュリア集合の経路に沿ってカメラを移動
const pointIndex = Math.floor((performance.now() * cameraSpeed) % points.length);
const point = points[pointIndex];
camera.position.x = point.x; // カメラのX座標を更新
camera.position.y = point.y; // カメラのY座標を更新
camera.position.z = point.z + 2; // カメラのZ座標を更新(オフセットを追加)
// カメラが常に集合の中心を見るように設定
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.render(scene, camera); // シーンをレンダリング
}
animate(); // アニメーションを開始
// ウィンドウリサイズ時の処理
window.addEventListener('resize', function () {
renderer.setSize(window.innerWidth, window.innerHeight); // レンダラーのサイズを更新
camera.aspect = window.innerWidth / window.innerHeight; // カメラのアスペクト比を更新
camera.updateProjectionMatrix(); // カメラの投影行列を更新
});
</script>
</body>
</html>
説明
ジュリア集合をプロットし、その点に沿ってカメラが移動するアニメーションを作成しました。
各点は色相 (hue) に基づいてカラフルにプロットされます。
カメラはジュリア集合の中心を常に見るようにし、少しずつ集合の中を移動するようにしています。
このコードを実行すると、ジュリア集合がカラフルに描画され、カメラがその中を飛び回る様子が3Dで表示されます。