import os
import webbrowser
from http.server import SimpleHTTPRequestHandler, HTTPServer
import threading
# HTMLコードを生成
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fire Simulation</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>
let scene, camera, renderer, particles = [];
const numParticles = 1000;
const numSteps = 100;
let currentStep = 0;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
for (let i = 0; i < numParticles; i++) {
let geometry = new THREE.SphereGeometry(0.05, 16, 16);
let material = new THREE.MeshBasicMaterial({ color: 0xff4500 });
let particle = new THREE.Mesh(geometry, material);
scene.add(particle);
particles.push(particle);
}
}
function simulateFire() {
// パーティクルの位置と速度を初期化
let positions = Array.from({ length: numParticles }, () => ({
x: 0, y: 0, z: 0,
vx: (Math.random() - 0.5) * 0.2,
vy: Math.random() * 0.1,
vz: (Math.random() - 0.5) * 0.2
}));
function step() {
for (let i = 0; i < numParticles; i++) {
positions[i].x += positions[i].vx;
positions[i].y += positions[i].vy;
positions[i].z += positions[i].vz;
// パーティクルを再配置
particles[i].position.set(positions[i].x, positions[i].y, positions[i].z);
// カラーの変更:高さに基づいて色を変更
let colorIntensity = Math.max(0, 1 - positions[i].y / 5);
particles[i].material.color.setHSL(0.1, 1.0, colorIntensity);
// 下に来たら再度上に飛ばす
if (positions[i].y > 5 || positions[i].y < -5) {
positions[i].x = 0;
positions[i].y = 0;
positions[i].z = 0;
}
}
}
function animate() {
requestAnimationFrame(animate);
step();
renderer.render(scene, camera);
}
window.addEventListener('resize', function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
animate();
}
init();
simulateFire();
</script>
</body>
</html>
"""
# HTMLファイルとして保存
html_file = 'fire_simulation.html'
with open(html_file, 'w') as file:
file.write(html_content)
# サーバーをバックグラウンドで起動
def run_server():
server_address = ('', 8000)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
# サーバーを別スレッドで実行
thread = threading.Thread(target=run_server)
thread.daemon = True
thread.start()
# デフォルトのブラウザでHTMLファイルを開く
webbrowser.open(f'http://localhost:8000/{html_file}')
# サーバー停止まで待機
try:
thread.join()
except KeyboardInterrupt:
print("Server stopped.")