2017-10-10 1 views
0

Ich fand alle Schnittpunkte zwischen dem Objekt und der Ebene, wie in diesem großen example. Aber jetzt möchte ich diese Punkte untereinander verbinden (in separate Arrays teilen), wo die Ebene passiert und sie wieder verbindet. Ich versuchte, sie nach der Entfernung zu verbinden, aber diese nicht geben ein effektives ErgebnisGruppierung Punkte nach Schnitt Ebene drei js

//SORT POINTS DISTANCE 
var pointsArray = []; //point after intersection 
var sortedPoints = []; 
var sortedPointsDis = []; 

sortedPoints.push(pointsArray.pop()); 

while(pointsArray.length) { 
    var distance = sortedPoints[sortedPoints.length - 1].distanceTo(pointsArray[0]); 
    var index = 0; 
    for(var i = 1; i < pointsArray.length; i++) { 
     var tempDistance = sortedPoints[sortedPoints.length - 1].distanceTo(pointsArray[i]); 
     if(tempDistance < distance) { 
      distance = tempDistance; 
      index = i; 
     } 
    } 
    sortedPoints.push(pointsArray.splice(index, 1)[0]); 
    sortedPointsDis.push(distance); 
} 

//GROUP POINTS 
var result = [[]]; 

for(var i = 0; i < sortedPoints.length; i++) { 
    var lastArr = result[result.length - 1]; 
    if(lastArr.length < 3) { 
     lastArr.push(sortedPoints[i]); 
    } else { 
     var distance = lastArr[0].distanceTo(sortedPoints[i]); 
     if(distance < sortedPointsDis[i - 1]) { 
      result.push([]); 
      lastArr = result[result.length - 1]; 
     } 
     lastArr.push(sortedPoints[i]); 
    } 
} 

JSfiddle. Ideen? Beispiele? Vielen Dank im Voraus für Ihre Antworten!

Antwort

1

Also, ja, diese Antwort basiert auf that one und erweitert es. Die Lösung ist grob und kann optimiert werden.

ich verwendet habe, modifizierte .equals() Methode von THREE.Vector3() (ich hoffe, dass es (oder so ähnlich) wird ein Teil des Kerns eines Tages, da es eine sehr nützliche Funktion ist), genommen von here:

THREE.Vector3.prototype.equals = function(v, tolerance) { 
    if (tolerance === undefined) { 
    return ((v.x === this.x) && (v.y === this.y) && (v.z === this.z)); 
    } else { 
    return ((Math.abs(v.x - this.x) < tolerance) && (Math.abs(v.y - this.y) < tolerance) && (Math.abs(v.z - this.z) < tolerance)); 
    } 
} 

enter image description here

Die Idee:

Wenn wir Schnittpunkte bekommen, an jedem Punkt, den wir Informationen darüber, welche face ein Punkt gehört. Dies bedeutet, dass es immer Punktepaare mit demselben Gesichtsindex gibt.

Dann finden wir rekursiv alle Konturen unserer Punkte Form.

Außerdem werden alle Punkte als nicht markiert markiert (.checked = false).

  1. Suchen Sie den ersten unmarkierten Punkt. Fügen Sie es dem Array der aktuellen Kontur hinzu.

  2. Finden Sie seinen Punkt (mit dem gleichen Gesichtsindex). Fügen Sie es dem Array der aktuellen Kontur hinzu.

  3. Suchen Sie nach einem unmarkierten Punkt, der dem zuletzt gefundenen Punkt am nächsten liegt. Makr es als überprüft .checked = true.

  4. Finden Sie seinen Punkt (mit dem gleichen Gesichtsindex). Markieren Sie es als überprüft .checked = true.

  5. prüfen, ob der letzte gefundene Punkt entspricht (mit einer gewissen Toleranz) mit dem ersten Punkt gefunden (der Anfang der Kontur)

    5.1. Wenn nein, dann fügen Sie einfach den letzten gefundenen Punkt im Array der aktuellen Kontur hinzu und gehen Sie zu Schritt 3.

    5.2. Wenn ja, dann klonen Sie den ersten Punkt der aktuellen Kontur und fügen Sie ihn zum Array der aktuellen Kontur hinzu, fügen Sie die Kontur zum Konturlinienfeld hinzu.

  6. Prüfen Sie, ob wir alle Punkte als markiert markiert haben.

    6.1. Wenn nein, dann gehen Sie zu Schritt 1.

    6.2. Wenn ja, sind wir fertig. Geben Sie das Array der Konturen zurück.

Modifizierte Funktion einen Schnittpunkt der Einstellung:

function setPointOfIntersection(line, plane, faceIdx) { 
    pointOfIntersection = plane.intersectLine(line); 
    if (pointOfIntersection) { 
    let p = pointOfIntersection.clone(); 
    p.faceIndex = faceIdx; 
    p.checked = false; 
    pointsOfIntersection.vertices.push(p); 
    }; 
} 

Wie Konturen bekommen und wie sie ziehen:

var contours = getContours(pointsOfIntersection.vertices, [], true); 

contours.forEach(cntr => { 
    let cntrGeom = new THREE.Geometry(); 
    cntrGeom.vertices = cntr; 
    let contour = new THREE.Line(cntrGeom, new THREE.LineBasicMaterial({ 
     color: Math.random() * 0xffffff 
    })); 
    scene.add(contour); 
    }); 

Wo

function getContours(points, contours, firstRun) { 
    console.log("firstRun:", firstRun); 

    let contour = []; 

    // find first line for the contour 
    let firstPointIndex = 0; 
    let secondPointIndex = 0; 
    let firsPoint, secondPoint; 
    for (let i = 0; i < points.length; i++) { 
    if (points[i].checked == true) continue; 
    firstPointIndex = i; 
    firstPoint = points[firstPointIndex]; 
    firstPoint.checked = true; 
    secondPointIndex = getPairIndex(firstPoint, firstPointIndex, points); 
    secondPoint = points[secondPointIndex]; 
    secondPoint.checked = true; 
    contour.push(firstPoint.clone()); 
    contour.push(secondPoint.clone()); 
    break; 
    } 

    contour = getContour(secondPoint, points, contour); 
    contours.push(contour); 
    let allChecked = 0; 
    points.forEach(p => { allChecked += p.checked == true ? 1 : 0; }); 
    console.log("allChecked: ", allChecked == points.length); 
    if (allChecked != points.length) { return getContours(points, contours, false); } 
    return contours; 
} 

function getContour(currentPoint, points, contour){ 
    let p1Index = getNearestPointIndex(currentPoint, points); 
    let p1 = points[p1Index]; 
    p1.checked = true; 
    let p2Index = getPairIndex(p1, p1Index, points); 
    let p2 = points[p2Index]; 
    p2.checked = true; 
    let isClosed = p2.equals(contour[0], tolerance); 
    if (!isClosed) { 
    contour.push(p2.clone()); 
    return getContour(p2, points, contour); 
    } else { 
    contour.push(contour[0].clone()); 
    return contour; 
    } 
} 

function getNearestPointIndex(point, points){ 
    let index = 0; 
    for (let i = 0; i < points.length; i++){ 
    let p = points[i]; 
    if (p.checked == false && p.equals(point, tolerance)){ 
     index = i; 
     break; 
    } 
    } 
    return index; 
} 

function getPairIndex(point, pointIndex, points) { 
    let index = 0; 
    for (let i = 0; i < points.length; i++) { 
    let p = points[i]; 
    if (i != pointIndex && p.checked == false && p.faceIndex == point.faceIndex) { 
     index = i; 
     break; 
    } 
    } 
    return index; 
} 

jsfiddle Beispiel r87.

+0

Kühl. Vielen Dank! Da dies einmal berechnet wird, denke ich, dass dies eine gute Lösung und eine gute Erklärung ist. Das funktioniert bei mir. Danke noch einmal. –