在 three.js 中找到一束平面 (3) 的交点
Finding the intersection point of a bundle of planes (3) in three.js
我正在尝试使用此 wolfram 页面底部的公式实现 3 平面相交:http://mathworld.wolfram.com/Plane-PlaneIntersection.html
If the three planes are each specified by a point xk and a unit normal vector
nk, then the unique point of intersection x is given by
x = (|n1 n2 n3|)^(-1) [(x1 · n1)(n2 x n3)+(x2 · n2)(n3 x n1)+(x3 · n3)(n3 x n2)],
where |n1 n2 n3| is the determinant of the matrix formed by writing the
vectors ni side-by-side. If two of the planes are parallel, then
|n1 n2 n3| = 0,
但这是我所能得到的,我的矩阵数学很糟糕,我对 three.js 矩阵也不是很好
var x1, x2, x3; // all clones
var n1, n2, n3; // all clones, normalized
var f1 = (x1.dot(n1)).something(n2.cross(n3));
var f2 = (x2.dot(n2)).something(n3.cross(n1));
var f3 = (x3.dot(n3)).something(n1.cross(n2));
var full = f1.add(f2).add(f3);
首先,“(x1 · n1)(n2 x n3)”是什么意思?我知道第一个是点积,部分是叉积,我该怎么做才能将它们组合起来
二、three.js中的矩阵部分怎么写
第一个:
(x1 · n1)(n2 x n3) 是什么意思?
点积 (x1 · n1) 产生一个标量值,即 x1 平行于 n1 的分量。
叉积 (n2 x n3) 产生垂直于 n2 和 n3 的向量。
因此,表达式 (x1 · n1)(n2 x n3) 是向量 (n2 x n3),scaled/stretched/elongated 由标量 (x1 · n1)。
因此,在 three.js 中计算变量 f1,
var cross23 = new THREE.Vector3();
cross23.crossVectors(n2, n3); // stores the cross product (n2 x n3) in cross23
var scalar = x1.dot(n1);
var f1 = cross23;
f1.multiplyScalar(scalar);
第二个:
要计算行列式 |n1 n2 n3|,首先创建矩阵,我们称之为 M。
var M = THREE.Matrix3();
现在,我们将按照文档规定设置 M 的组件 (http://threejs.org/docs/#Reference/Math/Matrix3)。
M.set(n1.x, n1.y, n1.z, n2.x, n2.y, n2.z, n3.x, n3.y, n3.z);
最后,我们将计算矩阵的行列式。
var det = M.determinant();
第三名:
上面,我们展示了如何计算 det、f1、f2 和 f3。现在,要计算平面的交点,我们现在必须计算表达式 det^-1 * (f1 + f2 + f3)。我们首先计算向量和,f1 + f2 + f3,如下所示。
var vectorSum = new THREE.Vector3(0, 0, 0);
vectorSum.add(f1);
vectorSum.add(f2);
vectorSum.add(f3);
现在,有了行列式和矢量和,我们就可以计算出最终答案,特别是平面的交集。
var planeIntersection = new THREE.Vector3(vectorSum.x/det, vectorSum.y/det, vectorSum.z/det);
这是一个随时可用的函数(根据下面 robertl 的回答汇编而成):
参数:平面 p1、p2、p3
return: 向量 3
function vertIntersectPlanes(p1, p2, p3)
{
let n1 = p1.normal, n2 = p2.normal, n3 = p3.normal;
let x1 = p1.coplanarPoint(new THREE.Vector3());
let x2 = p2.coplanarPoint(new THREE.Vector3());
let x3 = p3.coplanarPoint(new THREE.Vector3());
let f1 = new THREE.Vector3().crossVectors(n2, n3).multiplyScalar(x1.dot(n1));
let f2 = new THREE.Vector3().crossVectors(n3, n1).multiplyScalar(x2.dot(n2));
let f3 = new THREE.Vector3().crossVectors(n1, n2).multiplyScalar(x3.dot(n3));
let det = new THREE.Matrix3().set(n1.x, n1.y, n1.z, n2.x, n2.y, n2.z, n3.x, n3.y, n3.z).determinant();
let vectorSum = new THREE.Vector3().add(f1).add(f2).add(f3);
let planeIntersection = new THREE.Vector3(vectorSum.x / det, vectorSum.y / det, vectorSum.z / det);
return planeIntersection;
}
我正在尝试使用此 wolfram 页面底部的公式实现 3 平面相交:http://mathworld.wolfram.com/Plane-PlaneIntersection.html
If the three planes are each specified by a point xk and a unit normal vector
nk, then the unique point of intersection x is given by
x = (|n1 n2 n3|)^(-1) [(x1 · n1)(n2 x n3)+(x2 · n2)(n3 x n1)+(x3 · n3)(n3 x n2)],
where |n1 n2 n3| is the determinant of the matrix formed by writing the
vectors ni side-by-side. If two of the planes are parallel, then
|n1 n2 n3| = 0,
但这是我所能得到的,我的矩阵数学很糟糕,我对 three.js 矩阵也不是很好
var x1, x2, x3; // all clones
var n1, n2, n3; // all clones, normalized
var f1 = (x1.dot(n1)).something(n2.cross(n3));
var f2 = (x2.dot(n2)).something(n3.cross(n1));
var f3 = (x3.dot(n3)).something(n1.cross(n2));
var full = f1.add(f2).add(f3);
首先,“(x1 · n1)(n2 x n3)”是什么意思?我知道第一个是点积,部分是叉积,我该怎么做才能将它们组合起来
二、three.js中的矩阵部分怎么写
第一个:
(x1 · n1)(n2 x n3) 是什么意思?
点积 (x1 · n1) 产生一个标量值,即 x1 平行于 n1 的分量。
叉积 (n2 x n3) 产生垂直于 n2 和 n3 的向量。
因此,表达式 (x1 · n1)(n2 x n3) 是向量 (n2 x n3),scaled/stretched/elongated 由标量 (x1 · n1)。
因此,在 three.js 中计算变量 f1,
var cross23 = new THREE.Vector3();
cross23.crossVectors(n2, n3); // stores the cross product (n2 x n3) in cross23
var scalar = x1.dot(n1);
var f1 = cross23;
f1.multiplyScalar(scalar);
第二个:
要计算行列式 |n1 n2 n3|,首先创建矩阵,我们称之为 M。
var M = THREE.Matrix3();
现在,我们将按照文档规定设置 M 的组件 (http://threejs.org/docs/#Reference/Math/Matrix3)。
M.set(n1.x, n1.y, n1.z, n2.x, n2.y, n2.z, n3.x, n3.y, n3.z);
最后,我们将计算矩阵的行列式。
var det = M.determinant();
第三名:
上面,我们展示了如何计算 det、f1、f2 和 f3。现在,要计算平面的交点,我们现在必须计算表达式 det^-1 * (f1 + f2 + f3)。我们首先计算向量和,f1 + f2 + f3,如下所示。
var vectorSum = new THREE.Vector3(0, 0, 0);
vectorSum.add(f1);
vectorSum.add(f2);
vectorSum.add(f3);
现在,有了行列式和矢量和,我们就可以计算出最终答案,特别是平面的交集。
var planeIntersection = new THREE.Vector3(vectorSum.x/det, vectorSum.y/det, vectorSum.z/det);
这是一个随时可用的函数(根据下面 robertl 的回答汇编而成):
参数:平面 p1、p2、p3 return: 向量 3
function vertIntersectPlanes(p1, p2, p3)
{
let n1 = p1.normal, n2 = p2.normal, n3 = p3.normal;
let x1 = p1.coplanarPoint(new THREE.Vector3());
let x2 = p2.coplanarPoint(new THREE.Vector3());
let x3 = p3.coplanarPoint(new THREE.Vector3());
let f1 = new THREE.Vector3().crossVectors(n2, n3).multiplyScalar(x1.dot(n1));
let f2 = new THREE.Vector3().crossVectors(n3, n1).multiplyScalar(x2.dot(n2));
let f3 = new THREE.Vector3().crossVectors(n1, n2).multiplyScalar(x3.dot(n3));
let det = new THREE.Matrix3().set(n1.x, n1.y, n1.z, n2.x, n2.y, n2.z, n3.x, n3.y, n3.z).determinant();
let vectorSum = new THREE.Vector3().add(f1).add(f2).add(f3);
let planeIntersection = new THREE.Vector3(vectorSum.x / det, vectorSum.y / det, vectorSum.z / det);
return planeIntersection;
}