Это, вероятно, можно классифицировать как скорее математический вопрос, чем вопрос Three.js, однако я столкнулся с проблемой при использовании Three.
Скажем, у меня есть два экземпляра Vector3
, которые могут определять линию (P1 и P2 на изображении ниже).
Теперь предположим, что у меня также есть еще один экземпляр Vector3
для представления точки (P3). Я хочу вычислить вектор, который определяет направление от P3 к линии. Результирующий вектор также должен быть нормалью к линии.
Я полагаю, что это проблема с точечным/перекрестным произведением, но не могу понять.
Уравнение должно работать, даже если P1 и P2 определяют линию, не параллельную ни одной из декартовых осей.
Да, это вопрос скалярного произведения:
вычислить Vector3 vn:
vn = ( p2 - p1 ).normalize();
и вп:
vp = ( p3 - p1 );
Затем используйте скалярное произведение, чтобы вычислить проекцию vp на линию p2-p1:
v = vp.dot( vn ) * vn;
потом
p1 + v
точка пересечения, которую вы ищете
Для пользователей Three.js после выполнения шагов, предоставленных Jordi, вот некоторый код, который позволяет вам указать точку на линии.
Вместо того, чтобы вычислять v
следующим образом: v = 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.