three.js 模拟 WI-FI 信号强度热区图

来源:17-6 添加交互效果

希卡利

2024-11-15

老师,您好,想问一下 ,如图所示的这种效果的实现思路是什么样子的呀?有没有可以使用的插件之类的东西?
xia

写回答

1回答

yancy

2024-12-30

模型、光源这些应该没啥问题,主要就是针对障碍物的检测。


检查信号路径是否被墙壁阻挡: 通过射线检测(Raycasting)检查从信号源到目标点的路径是否被墙壁遮挡。如果有遮挡,则衰减信号强度。可以看下下方的实现

// 1. 创建场景、相机和渲染器const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 2. 创建地面(模拟 Wi-Fi 信号区域)const geometry = new THREE.PlaneGeometry(10, 10, 10, 10);const material = new THREE.MeshBasicMaterial({  color: 0xffffff, // 初始颜色
  side: THREE.DoubleSide,  vertexColors: true  // 启用顶点颜色});const plane = new THREE.Mesh(geometry, material);
plane.rotation.x = Math.PI / 2;
scene.add(plane);// 3. 创建墙壁(遮挡物)const wallGeometry = new THREE.BoxGeometry(1, 5, 0.1);  // 创建一面薄墙const wallMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });const wall = new THREE.Mesh(wallGeometry, wallMaterial);
wall.position.set(4, 2.5, 0);  // 将墙壁放置到特定位置scene.add(wall);// 4. 定义一个简单的信号衰减模型function calculateSignalStrength(x, z, signalSource) {  const distance = Math.sqrt(x * x + z * z);  // 计算从信号源到目标点的距离
  let signalStrength = Math.max(0, 1 - distance / 10);  // 信号衰减公式

  // 使用射线检测判断是否被墙壁遮挡
  const raycaster = new THREE.Raycaster();
  raycaster.origin.set(signalSource.x, signalSource.y, signalSource.z);
  raycaster.direction.set(x - signalSource.x, 0, z - signalSource.z);  // 计算目标方向

  const intersects = raycaster.intersectObject(wall);  // 检查射线是否与墙壁相交
  if (intersects.length > 0) {    // 如果射线与墙壁相交,信号受到阻挡
    signalStrength *= 0.3;  // 阻挡的情况下信号强度衰减
  }  return signalStrength;
}// 5. 更新热力图的颜色function updateHeatmap() {  const vertices = geometry.attributes.position.array;  for (let i = 0; i < vertices.length; i += 3) {    const x = vertices[i];    const z = vertices[i + 2];    // 根据位置计算信号强度
    const signalStrength = calculateSignalStrength(x, z, new THREE.Vector3(0, 0, 0));  // 信号源位置为 (0, 0, 0)

    // 使用信号强度来决定颜色
    const color = new THREE.Color();
    color.setHSL((1 - signalStrength) / 2, 1, 0.5);  // 将信号强度映射到颜色,绿色为强信号,红色为弱信号

    // 将颜色应用到顶点
    geometry.attributes.color.array[i] = color.r;
    geometry.attributes.color.array[i + 1] = color.g;
    geometry.attributes.color.array[i + 2] = color.b;
  }  // 通知渲染器更新颜色
  geometry.attributes.color.needsUpdate = true;
}// 6. 渲染循环function animate() {  requestAnimationFrame(animate);  updateHeatmap();  // 更新热力图
  renderer.render(scene, camera);
}

camera.position.z = 5;animate();// 为了实现动态效果,使用 orbitControlsconst controls = new THREE.OrbitControls(camera, renderer.domElement);


0
0

WebGL+Three.js 入门与实战,系统学习 Web3D 技术

前端的技术蓝海,涨薪好选择

1114 学习 · 327 问题

查看课程