citys

城市边界电子围栏

初始化摄像头、灯光等

  let renderer, scene, camera, stats, gui, texture;
  renderer = new THREE.WebGLRenderer({
    logarithmicDepthBuffer: true,
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.getElementById("hello3D").appendChild(renderer.domElement);

  scene = new THREE.Scene();
  // AxesHelper:辅助观察的坐标系
  const axesHelper = new THREE.AxesHelper(150);
  scene.add(axesHelper);

  camera = new THREE.PerspectiveCamera(30,window.innerWidth / window.innerHeight,0.1,2000);

  // 设置相机 在 threejs 三维坐标系中的位置
  camera.position.set(0, 0, 150);

  const controls = new OrbitControls(camera, renderer.domElement);

  const ambient = new THREE.AmbientLight(0xffffff, 1);
  scene.add(ambient);

城市围栏

以河南省城市数据为例子,边界线 去高德或者datav中自己过去,本样例是使用的高德api获取的处理的边界线
threejs 是以三角形确定面的
以下代码为了后面的贴图,直接创建了uv数组
uv的数据一定要和三角形的数据一致,一个三角形对应三个坐标,可以这样理解:一个面由两个三角形组成,一个三角形对应的uv是三个坐标

const depth = 3;
city.forEach((polygon) => {
  // 三角形点
  const vec3List = [];
  // 三角面
  const faceList = [];

  // uv 坐标:一张图由四个点组成分别为坐标:t0、t1、t2、t3,
  const uvList = [];
  const t0 = [0, 0];
  const t1 = [1, 0];
  const t2 = [1, 1];
  const t3 = [0, 1];

  for (let i = 0; i < polygon.length; i++) {
    let [x, y] = projection(polygon[i]);

    // 根据数组创建三角形点的顺序数组
    vec3List.push([x, y, 0]);
    vec3List.push([x, y, -depth]);
  }
  // 根据三角形点组成面的数组
  for (let i = 0; i < vec3List.length - 2; i++) {
    if (i % 2 == 0) {
      // 下三角
      const face = [
        ...vec3List[i],
        ...vec3List[i + 2],
        ...vec3List[i + 1],
      ];
      Array.prototype.push.apply(faceList, face);
      // uv 一定要和三角形面一致,一个三角形面对应三个坐标
      const uv = [...t0, ...t1, ...t3];
      Array.prototype.push.apply(uvList, uv);
    } else {
      // 上三角
      const face = [
        ...vec3List[i],
        ...vec3List[i + 2],
        ...vec3List[i + 1],
      ];
      Array.prototype.push.apply(faceList, face);
      const uv = [...t3, ...t2, ...t1];
      Array.prototype.push.apply(uvList, uv);
    }
  }
  const geometryWall = new THREE.BufferGeometry();
  geometryWall.setAttribute(
    "position",
    new THREE.BufferAttribute(new Float32Array(faceList), 3)
  );
  geometryWall.setAttribute(
    "uv",
    new THREE.BufferAttribute(new Float32Array(uvList), 2)
  );
  // 计算法向量
  geometryWall.computeVertexNormals();
  geometryWall.computeBoundingBox();
  const max = geometryWall.boundingBox.max;
  const min = geometryWall.boundingBox.min;
  console.log("max-min:", max, min);
  texture = new THREE.TextureLoader().load(
    "./textures/linearGradient1.png"
  );
  //  texture = generateTexture(128, "#FFD500");
  texture.wrapS = THREE.RepeatWrapping;
  texture.wrapT = THREE.RepeatWrapping;
  const materialWall = new THREE.MeshBasicMaterial({
    color: "#0088ff",
    transparent: true,
    opacity:0.9,
    depthTest: false,
    side: THREE.DoubleSide,
    // map: texture,
  });
  const meshWall = new THREE.Mesh(geometryWall, materialWall);
  meshWall.scale.set(5,5,1)
  meshWall.rotation.x = Math.PI *0.8 

  meshWall.updateMatrix() 
  scene.add(meshWall);
  // 设置 uv贴图
});
renderer.render(scene, camera); //执行渲染操作
// 需要这个,要不坐标系 不显示
const controls = new OrbitControls(camera, renderer.domElement);
function render() {
  renderer.render(scene, camera);
  requestAnimationFrame(render); 
}
render();

效果:
河南省城市围栏

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值