threejs 几何运算

144 阅读2分钟

1.已知方向向量direction和起始点位originPosition,求将起始点位沿方向向量移动距离d后的结束点位。
方式一

const endPosition = originPosition.clone().add(direction.clone().multiplyScalar(d));
// 同理减去一段距离
const endPosition = originPosition.clone().sub(direction.clone().multiplyScalar(d));

方式二

 const endPosition = originPosition.clone().addScaledVector(direction.clone(), d);

2.已知点位A、B判断点C在向量AB左侧还是右侧
使用向量的叉乘(叉积),向量的叉乘的结果为一个垂直于该平面的向量,方向可以根据右手螺旋定则来判断。

const AC = c.clone().sub(A).normalize(); // AC向量的单位向量
const crossVector = B.cloen().sub(A).normalize().cross(AC); // AB向量与AC向量的单位向量的叉积
// 根据右手螺旋定则 确定朝向即可对应y的正负
if(crossVector.y>0){
// 右侧
}else if(crossVector.y<0){
// 左侧
}

3.获取两个点的中间点位

const midpoint = new THREE.Vector3();
midpoint.addVectors(startPoint, endPoint).multiplyScalar(0.5);

4.两点之间均匀取点

const point = new THREE.Vector3().lerpVectors(outsideMeeting, curPoint, t);

5.获取向量的交点

  // 获取两个向量的交点
  getIntersection(vector1Start, vector1End, vector2Start, vector2End) {
    // 创建射线
    const ray = new THREE.Ray(vector1Start, vector1End.clone().sub(vector1Start).normalize());

    // 创建平面
    const plane = new THREE.Plane().setFromCoplanarPoints(
      vector2Start,
      vector2End,
      vector2Start.clone().cross(vector2End)
    );
    const d1 = vector1End.clone().sub(vector1Start).normalize();
    const d2 = vector2End.clone().sub(vector2Start).normalize();
    const dotValue = d1.clone().dot(d2);

    // 获取交点
    const intersection = new THREE.Vector3();
    const intersectPoint = ray.intersectPlane(plane, intersection);

    if (dotValue === -1 || !intersectPoint) {
      return vector1End;
    }
    return intersectPoint;
  }

6.平面内旋转获取结束点位

  // 平面内旋转向量后的结束点位
  /**
   *
   * @param {*} startPoint  起始点位
   * @param {*} centerPoint  圆心
   * @param {*} radius      半径
   * @param {*} radians    旋转的弧度
   */
  getRotatedEndPoint(startPoint, centerPoint, radius, radians) {
    const CP = startPoint.clone().sub(centerPoint).normalize();
    const rotationMatrix = new THREE.Matrix4().makeRotationAxis(
      new THREE.Vector3(0, 1, 0),
      radians
    );
    const rotatedCP = CP.applyMatrix4(rotationMatrix);
    const nextPosition = centerPoint
      .clone()
      .add(rotatedCP.clone().normalize().multiplyScalar(radius));
    return nextPosition;
  }

7.将方向向量应用四元数之后得到新的方向向量

     let baseOutDirection = new THREE.Vector3();// 原始方向 
      // 将旋转角转化为四元数
      const quaternion = new THREE.Quaternion();
      quaternion.setFromEuler(insModel.rotation);
      // 将方向向量转化为四元数 由方向 new THREE.Vector3(1, 0, 0) 到 baseOutDirection 组成的四元数
      const directionQuaternion = new THREE.Quaternion();
      directionQuaternion.setFromUnitVectors(new THREE.Vector3(1, 0, 0), baseOutDirection);
      const newDirectionQuaternion = quaternion.clone().multiply(directionQuaternion);
      const newDirection = new THREE.Vector3(1, 0, 0);
      baseOutDirection = newDirection.applyQuaternion(newDirectionQuaternion);