所以,是的,这个答案基于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));
}
}
的想法:
当我们得到的交叉点,我们添加信息的每一点关于它面临一个点所属。这意味着总是有相同面点索引的点对。
然后,我们递归地找到我们点的形式的所有轮廓。
此外,所有点标记为未选中(.checked = false
)。
找到第一个未选中的点。将它添加到当前轮廓的数组中。
找到它的配对点(具有相同的脸部指数)。将它添加到当前轮廓的数组中。
找到一个未检查的点,最接近最后找到的点。 Makr它作为检查.checked = true
。
找到它的配对点(具有相同的脸部指数)。将其标记为已选中.checked = true
。
检查,如果最后发现点等于(有一些公差)的首次发现点(轮廓的开始)
5.1。如果不是,则只需在当前轮廓的数组中添加最后找到的点,然后转到步骤3。
5.2。如果是,则克隆当前轮廓的第一个点并将其添加到当前轮廓的阵列中,将轮廓添加到轮廓阵列。
检查,如果我们有所有标记为检查点。
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。
很酷。非常感谢你!由于这是计算一次,在负载,我认为这是一个很好的解决方案和很好的解释^^这是为我工作。再次感谢。 –