2017-10-10 75 views
0

我找到了物体和平面之间的所有交点,如在这个伟大的example中。但是现在我想将它们之间的这些点连接起来(划分成单独的阵列),在这里飞机通过并再次连接它们。我试图通过距离来连接它们,但是这并没有给一个有效的结果切割平面三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。 想法?例子?预先感谢您的回复!

回答

1

所以,是的,这个答案基于that one并扩展它。解决方案很粗糙,可以进行优化。

我用改性THREE.Vector3().equals()方法(我希望它(或类似的东西)将是核心每一天的一部分,因为它是一个非常有用的功能),从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

的想法:

当我们得到的交叉点,我们添加信息的每一点关于它面临一个点所属。这意味着总是有相同面点索引的点对。

然后,我们递归地找到我们点的形式的所有轮廓。

此外,所有点标记为未选中(.checked = false)。

  1. 找到第一个未选中的点。将它添加到当前轮廓的数组中。

  2. 找到它的配对点(具有相同的脸部指数)。将它添加到当前轮廓的数组中。

  3. 找到一个未检查的点,最接近最后找到的点。 Makr它作为检查.checked = true

  4. 找到它的配对点(具有相同的脸部指数)。将其标记为已选中.checked = true

  5. 检查,如果最后发现点等于(有一些公差)的首次发现点(轮廓的开始)

    5.1。如果不是,则只需在当前轮廓的数组中添加最后找到的点,然后转到步骤3

    5.2。如果是,则克隆当前轮廓的第一个点并将其添加到当前轮廓的阵列中,将轮廓添加到轮廓阵列。

  6. 检查,如果我们有所有标记为检查点。

    6.1。如果不是,则转到步骤1

    6.2。如果是,我们就完成了。返回轮廓数组。

设置一个交点的修改功能:

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

如何获得轮廓以及如何吸引他们:

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

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例子R87。

+0

很酷。非常感谢你!由于这是计算一次,在负载,我认为这是一个很好的解决方案和很好的解释^^这是为我工作。再次感谢。 –