Jack Franzen
Jack Franzen

Reputation: 778

Finding the intersection point of a bundle of planes (3) in three.js

I'm Trying to implement 3-plane intersection using the formula at the bottom of this wolfram page here: 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, 

But this is as far as I can get, my matrix math is awful and I'm not that good with three.js matrices

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);

First off, what is '(x1 · n1)(n2 x n3)' supposed to mean? I know the first one is dot product and the section is cross product, what do I do to combine them

Second, how do I write the matrix portion in three.js

Upvotes: 0

Views: 2100

Answers (2)

Drout
Drout

Reputation: 335

Here's a ready to use function (assembled from the answer from robertl below):

arguments: Planes p1,p2,p3 return: Vector3

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;
}

Upvotes: 1

robertl
robertl

Reputation: 69

First:

What does (x1 · n1)(n2 x n3) mean?

The dot product (x1 · n1) produces a scalar value, namely the component of x1 parallel to n1.

The cross product (n2 x n3) produces a vector perpendicular to both n2 and n3.

Thus, the expression (x1 · n1)(n2 x n3) is the vector (n2 x n3), scaled/stretched/elongated by the scalar (x1 · n1).

Therefore, in three.js, to compute your variable 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);

Second:

To compute the determinant |n1 n2 n3|, first create the matrix, which we'll call M.

var M = THREE.Matrix3();

Now, we'll set the components of M as the documentation prescribes (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);

Finally, we'll compute the determinant of the matrix.

var det = M.determinant();

Third:

Above, we've shown how to calculate det, f1, f2, and f3. Now, to compute the intersection of the planes, we must now calculate the expression det^-1 * (f1 + f2 + f3). We first compute the vector sum, f1 + f2 + f3, as follows.

var vectorSum = new THREE.Vector3(0, 0, 0);
vectorSum.add(f1);
vectorSum.add(f2);
vectorSum.add(f3);

Now, with both the determinant and the vector sum, we can compute the final answer, specifically the intersection of the planes.

var planeIntersection = new THREE.Vector3(vectorSum.x/det, vectorSum.y/det, vectorSum.z/det);

Upvotes: 1

Related Questions