javascript - Three JS: encuentra todos los puntos donde una malla se cruza con un plano
3d three.js (1)
He creado una escena three.js que incluye un plano que se cruza con una malla. Lo que me gustaría hacer es obtener una serie de puntos para todas las ubicaciones donde un borde de la malla cruza el plano. He buscado soluciones y parece que no puedo encontrar nada.
Aquí hay una imagen de lo que tengo actualmente:
Y aquí he resaltado las coordenadas que estoy tratando de reunir:
Si alguien puede señalarme en la dirección correcta, sería muy apreciado.
Gracias,
S
Esta no es la solución definitiva. Este es solo un punto desde el que puede comenzar.
UPD: Here hay una extensión de esta respuesta, cómo formar contornos a partir de puntos dados.
Además, se refiere a
esta pregunta SO
con asombrosas respuestas de WestLangley y Lee Stemkoski sobre el método
THREE.Object3D()
de
THREE.Object3D()
.
Imaginemos que desea encontrar puntos de intersección de una geometría habitual (por ejemplo,
THREE.DodecahedronGeometry()
).
La idea:
-
THREE.Plane()
tiene el.intersectLine ( line, optionalTarget )
-
Una malla contiene caras (
THREE.Face3()
) -
Cada cara tiene propiedades a
a, b, c
, donde se almacenan los índices de vértices. -
Cuando conocemos índices de vértices, podemos obtenerlos de la matriz de
vertices
-
Cuando conocemos las coordenadas de los vértices de una cara, podemos construir tres objetos
THREE.Line3()
-
Cuando tenemos tres líneas, podemos verificar si nuestro avión las intersecta.
-
Si tenemos un punto de intersección, podemos almacenarlo en una matriz.
-
Repita los pasos 3 a 7 para cada cara de la malla.
Alguna explicación con código:
Tenemos
plane
que es
THREE.PlaneGeometry()
y
obj
que es
THREE.DodecahedronGeometry()
Entonces,
THREE.Plane()
un
THREE.Plane()
:
var planePointA = new THREE.Vector3(),
planePointB = new THREE.Vector3(),
planePointC = new THREE.Vector3();
var mathPlane = new THREE.Plane();
plane.localToWorld(planePointA.copy(plane.geometry.vertices[plane.geometry.faces[0].a]));
plane.localToWorld(planePointB.copy(plane.geometry.vertices[plane.geometry.faces[0].b]));
plane.localToWorld(planePointC.copy(plane.geometry.vertices[plane.geometry.faces[0].c]));
mathPlane.setFromCoplanarPoints(planePointA, planePointB, planePointC);
Aquí, tres vértices de cualquier cara del
plane
son coplanares, por lo que podemos crear
mathPlane
partir de ellos, utilizando el método
.setFromCoplanarPoints()
.
Luego recorreremos las caras de nuestro
obj
:
var a = new THREE.Vector3(),
b = new THREE.Vector3(),
c = new THREE.Vector3();
obj.geometry.faces.forEach(function(face) {
obj.localToWorld(a.copy(obj.geometry.vertices[face.a]));
obj.localToWorld(b.copy(obj.geometry.vertices[face.b]));
obj.localToWorld(c.copy(obj.geometry.vertices[face.c]));
lineAB = new THREE.Line3(a, b);
lineBC = new THREE.Line3(b, c);
lineCA = new THREE.Line3(c, a);
setPointOfIntersection(lineAB, mathPlane);
setPointOfIntersection(lineBC, mathPlane);
setPointOfIntersection(lineCA, mathPlane);
});
dónde
var pointsOfIntersection = new THREE.Geometry();
...
var pointOfIntersection = new THREE.Vector3();
y
function setPointOfIntersection(line, plane) {
pointOfIntersection = plane.intersectLine(line);
if (pointOfIntersection) {
pointsOfIntersection.vertices.push(pointOfIntersection.clone());
};
}
Al final haremos visibles nuestros puntos:
var pointsMaterial = new THREE.PointsMaterial({
size: .5,
color: "yellow"
});
var points = new THREE.Points(pointsOfIntersection, pointsMaterial);
scene.add(points);
Ejemplo de jsfiddle . Presione el botón para obtener los puntos de intersección entre el plano y el dodecaedro.