2017-02-20 30 views
8

Я создал сцену three.js, которая включает в себя плоскость, пересекающую сетку. То, что я хотел бы сделать, это получить массив точек для всех местоположений, где край сетки пересекает плоскость. Я хорошо разбираюсь в решениях и не могу найти ничего.Three JS - Найти все точки, где сетка пересекает плоскость

Вот образ того, что я в настоящее время:

enter image description here

И тут я обратил внимание на координаты я пытаюсь собрать:

enter image description here

Если кто-нибудь может мне точку в правильном направлении, это было бы очень полезно.

Благодаря,

S

ответ

16

Это не окончательное решение. Это всего лишь точка, из которой вы можете начать.

UPD: Here является продолжением этого ответа, как сформировать контуры из заданных точек.

Кроме того, это называется this SO question с удивительным anwers из WestLangley и Ли 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. Когда мы знаем координаты вершин грани, мы можем построить три THREE.Line3() объекты

  6. Когда мы имеем три линии, мы можем проверить, пересекает ли их плоскость.

  7. Если у нас есть точка пересечения, мы можем сохранить его в массиве.

  8. Повторите шаги 3 - 7 для каждой грани сетки

Некоторые объяснения с кодом:

У нас есть 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 пример. Нажмите кнопку там, чтобы получить точки пересечения между плоскостью и додекаэдром.

+3

Nice. Возможно также соединить точки ... https://jsfiddle.net/8uxw667m/4/ – WestLangley

+0

@WestLangley Да, отлично! Я действительно забыл добавить такую ​​очевидную визуальную вещь. Благодаря! – prisoner849

+0

хорошее решение. Я подумал о том, как решить точку (пересекаемую точку) между двумя точками, теперь это, по-видимому, не требуется. –