计算由两点定义的直线朝向另一点的法向量

Calculate the normal vector of a line defined by two points toward another point

这可能更像是一道数学题,而不是一道 Three.js 题,但是我在使用 Three 时遇到过这个问题。

假设我有两个 Vector3 实例可以定义一条线(下图中的 P1 和 P2)。

现在假设我还有一个 Vector3 的另一个实例来表示一个点 (P3)。我想计算定义从 P3 到线的方向的向量。生成的向量也应该垂直于直线。

我认为这是一个 dot/cross 产品问题,但不太明白。

即使 P1 和 P2 定义了一条不平行于任何笛卡尔轴的线,方程也应该有效。

是的,是点积的问题:

计算 Vector3 vn:

vn = ( p2 - p1 ).normalize();

和副总裁:

vp = ( p3 - p1 );

然后用点积计算vp在p2-p1直线上的投影:

v = vp.dot( vn ) * vn;

然后

p1 + v

是你要找的交点

对于 Three.js 用户,在按照 Jordi 提供的步骤进行操作后,这里有一些代码可以让您向直线移动一个点。

而不是像这样计算 vv = vp.dot( vn ) * vn - Vector3 有一个方法 projectOnVector 可以使它更平滑一些。

interface IProjectTowardAxis {
  points: Vector3[];
  /** The first point to define a line */
  p1: Vector3;
  /** The second point to define a line */
  p2: Vector3;
  /** lerp distance from 0 to 1 */
  alpha: number;
}

const projectPointsTowardAxis = (options: IProjectTowardAxis): Vector3[] => {
  const {points, p1, p2, alpha} = options;

  const vn = p2.clone().sub(p1).normalize();

  for (let pt of points) {
    const vp = pt.clone().sub(p1);
    const v = vp.clone().projectOnVector(vn);
    vp.copy(p1).add(v);
    pt.lerp(vp, alpha);
  }
  return points;
};

使用这个函数,外波被投射到 z-axis。