threejs 坐标转换

940 阅读1分钟

最近一直在做有关于地球的项目,经纬度之类的转换都要做,马上要做墨卡托投影和经纬度的转换了,先把以前的其他方法分享

```  function getPosition(longitude, latitude, radius) {
    // 传入经纬度和球半径,可以得到三维空间中该经纬度对应点的坐标
    var lg = THREE.Math.degToRad(longitude + 90)
    var lt = THREE.Math.degToRad(latitude)
    var temp = radius * Math.cos(lt)
    // 获取x,y,z坐标
    var x = temp * Math.sin(lg)
    var y = radius * Math.sin(lt)
    var z = temp * Math.cos(lg)
    /*        return {
                x: x,
                y: y,
                z: z
            }*/
    return new THREE.Vector3(x, y, z)
  }
    // 获取朝向方法  本人实现的需求是一个球上的实体,切球面放置
  function getPointRotation(point) {
    let rotationMatrix = new THREE.Matrix4()
    let q1 = new THREE.Quaternion()
    rotationMatrix.lookAt(
      point,
      new THREE.Vector3(),
      new THREE.Vector3(0, 0, 1)
    )
    q1.setFromRotationMatrix(rotationMatrix)
    let r1 = new THREE.Euler()
    r1.setFromQuaternion(q1)
    return r1
  }
  
  
```js
```function getSCL(startPoint, endPoint) {
//此方法为 三次贝塞尔曲线的中间两个控制点的求法,网上其他的方法有些老旧使用会报错,因为ray.at方法在新版本的threejs中和旧版本有差异,自己计算控制点控制曲线的轨迹
  let v0 = startPoint
  let v3 = endPoint

  // 计算向量夹角
  let angle = v0.angleTo(v3) //* 270 / Math.PI / 10; // 0 ~ Math.PI
  let aLen = angle / 2 //* 50,
  let hLen = angle * angle //* 120;
  let p0 = new THREE.Vector3(0, 0, 0)

  // 法线向量
  let rayLine = new THREE.Ray(p0, getVCenter(v0.clone(), v3.clone()))

  // 顶点坐标

  let vtop = rayLine
    .at(
      hLen / rayLine.at(1, new THREE.Vector3()).distanceTo(p0),
      new THREE.Vector3()
    )
    .multiplyScalar(-1)

  //console.log(aLen,hLen,vtop);

  // 控制点坐标
  let v1 = getLenVcetor(v0.clone(), vtop, aLen)
  let v2 = getLenVcetor(v3.clone(), vtop, aLen)

  // 绘制贝塞尔曲线
  //   let curve = new THREE.CubicBezierCurve3(v0, v1, v2, v3)
//   console.log(v1, v2)

  //   return curve
}
// 计算v1,v2 的中点
function getVCenter(v1, v2) {
  let v = v1.add(v2)
  return v.divideScalar(2)
}

// 计算V1,V2向量固定长度的点
function getLenVcetor(v1, v2, len) {
  let v1v2Len = -v1.distanceTo(v2)
  return v1.lerp(v2, len / v1v2Len)
}