let scene, camera, renderer, controls; function initThree() { // 初始化场景 scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(800, 600); document.getElementById('visualization').appendChild(renderer.domElement); // 添加光源 const light = new THREE.AmbientLight(0xffffff, 0.8); scene.add(light); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(0, 1, 1); scene.add(directionalLight); // 设置相机位置 camera.position.set(10, 10, 10); camera.lookAt(0, 0, 0); // 添加轨道控制器 controls = new THREE.OrbitControls(camera, renderer.domElement); } function clearScene() { while(scene.children.length > 0){ scene.remove(scene.children[0]); } } function renderContainer(container) { // 绘制集装箱线框 const geometry = new THREE.BoxGeometry( container.Length, container.Width, container.Height ); const edges = new THREE.EdgesGeometry(geometry); const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial({ color: 0x000000 }) ); scene.add(line); } function renderBoxes(placements) { placements.forEach(pos => { const geometry = new THREE.BoxGeometry(pos.Length, pos.Width, pos.Height); const material = new THREE.MeshPhongMaterial({ color: 0x00ff00, transparent: true, opacity: 0.7 }); const cube = new THREE.Mesh(geometry, material); cube.position.set( pos.X + pos.Length/2, pos.Y + pos.Width/2, pos.Z + pos.Height/2 ); scene.add(cube); }); } async function calculate() { // 获取输入值 const container = { Length: parseFloat(document.getElementById('contLength').value), Width: parseFloat(document.getElementById('contWidth').value), Height: parseFloat(document.getElementById('contHeight').value), MaxWeight: parseFloat(document.getElementById('contWeight').value) }; const box = { Length: parseFloat(document.getElementById('boxLength').value), Width: parseFloat(document.getElementById('boxWidth').value), Height: parseFloat(document.getElementById('boxHeight').value), Weight: parseFloat(document.getElementById('boxWeight').value) }; // 发送请求 const response = await fetch('/api/calculate', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ container, box }) }); const result = await response.json(); // 更新可视化 clearScene(); renderContainer(container); renderBoxes(result.placements); } // 初始化 initThree(); animate(); function animate() { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); }