三个JS - 查找网格与平面相交的所有点

时间:2017-02-20 15:32:24

标签: javascript 3d three.js

我创建了一个three.js场景,其中包含一个与网格相交的平面。我想要做的是为网格边缘穿过平面的所有位置获取一个点阵列。我已经很好地寻找解决方案,似乎找不到任何东西。

以下是我目前所拥有的图片:

enter image description here

在这里,我突出了我想要收集的坐标:

enter image description here

如果有人能指出我正确的方向,那将是最受欢迎的。

谢谢,

取值

1 个答案:

答案 0 :(得分:22)

这不是最终解决方案。这只是你可以从哪里开始的。

UPD:Here是此答案的扩展,如何从给定点形成轮廓

此外,它引用了this SO question来自WestLangley和Lee Stemkoski的关于.localToWorld() THREE.Object3D()方法的精彩答案。

让我们假设您想要找到常用几何体的交点(例如THREE.DodecahedronGeometry())。

enter image description here

这个想法:

  1. THREE.Plane()拥有.intersectLine ( line, optionalTarget )方法

  2. 网格包含面(THREE.Face3()

  3. 每个面都有a, b, c个属性,其中存储了顶点索引。

  4. 当我们知道顶点索引时,我们可以从vertices

  5. 的数组中获取它们
  6. 当我们知道一个面的顶点坐标时,我们可以构建三个THREE.Line3()个对象

  7. 当我们有三条线时,我们可以检查我们的平面是否与它们相交。

  8. 如果我们有一个交叉点,我们可以将它存储在一个数组中。

  9. 对网格的每个面重复步骤3 - 7

  10. 代码的一些解释:

    我们有plane THREE.PlaneGeometry()obj THREE.DodecahedronGeometry()

    所以,让我们创建一个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);
    

    此处,plane的任意面的三个顶点是共面的,因此我们可以使用mathPlane方法从它们创建.setFromCoplanarPoints()

    然后我们将遍历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);
      });
    

    ,其中

    var pointsOfIntersection = new THREE.Geometry();
    ...
    var pointOfIntersection = new THREE.Vector3();
    

    function setPointOfIntersection(line, plane) {
      pointOfIntersection = plane.intersectLine(line);
      if (pointOfIntersection) {
        pointsOfIntersection.vertices.push(pointOfIntersection.clone());
      };
    }
    

    最后,我们将使我们的观点可见:

    var pointsMaterial = new THREE.PointsMaterial({
        size: .5,
        color: "yellow"
      });
    var points = new THREE.Points(pointsOfIntersection, pointsMaterial);
    scene.add(points);
    

    jsfiddle示例。按下那里的按钮以获得飞机和十二面体之间的交叉点。