public bool IsAlmostEqualTo(Line3D other) { return(IsAlmostEqualTo(other, Extension.SMALL_NUMBER)); }
public bool IsAlmostEqualTo(Line3D other, double toterance) { return((Start.IsAlmostEqualTo(other.Start, toterance) && End.IsAlmostEqualTo(other.End, toterance)) || (Start.IsAlmostEqualTo(other.End, toterance) && End.IsAlmostEqualTo(other.Start, toterance))); }
/// <summary> /// 直线和线段相交 /// </summary> /// <param name="limitedCurve">线段</param> /// <returns></returns> public Vector3D IntersectStraightLine2(Line3D limitedCurve) { double x0 = Origin.X, y0 = Origin.Y, z0 = Origin.Z, x1 = limitedCurve.Start.X, y1 = limitedCurve.Start.Y, z1 = limitedCurve.Start.Z, l0 = Direction.X, m0 = Direction.Y, n0 = Direction.Z, l1 = limitedCurve.Direction.X, m1 = limitedCurve.Direction.Y, n1 = limitedCurve.Direction.Z, deltaLM = l0 * m1 - m0 * l1, deltaMN = m0 * n1 - n0 * m1, deltaLN = l0 * n1 - n0 * l1, t0, t1; if (deltaLM.AreEqual(0) && deltaLN.AreEqual(0) && deltaMN.AreEqual(0)) { return(null); } if (!deltaLM.AreEqual(0)) { t0 = (m1 * x1 - l1 * y1 - m1 * x0 + l1 * y0) / deltaLM; if (!l1.AreEqual(0)) { t1 = (x0 + l0 * t0 - x1) / l1; } else { t1 = (y0 + m0 * t0 - y1) / m1; } double zTry1 = z0 + n0 * t0, zTry2 = z1 + n1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (zTry1.AreEqual(zTry2) && intersection.IsOnLine(limitedCurve)) { return(intersection); } else { return(null); } } else if (!deltaLN.AreEqual(0)) { t0 = (n1 * x1 - l1 * z1 - n1 * x0 + l1 * z0) / deltaLN; if (!l1.AreEqual(0)) { t1 = (x0 + l0 * t0 - x1) / l1; } else { t1 = (z0 + n0 * t0 - z1) / n1; } double yTry1 = y0 + m0 * t0, yTry2 = y1 + m1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (yTry1.AreEqual(yTry2) && intersection.IsOnLine(limitedCurve)) { return(intersection); } else { return(null); } } else { t0 = (n1 * y1 - m1 * z1 - n1 * y0 + m1 * z0) / deltaMN; if (!m1.AreEqual(0)) { t1 = (y0 + m0 * t0 - y1) / m1; } else { t1 = (z0 + n0 * t0 - z1) / n1; } double xTry1 = x0 + l0 * t0, xTry2 = x1 + l1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (xTry1.AreEqual(xTry2) && intersection.IsOnLine(limitedCurve)) { return(intersection); } else { return(null); } } }
/// <summary> /// 线段和线段相交 /// </summary> /// <param name="curve"></param> /// <returns></returns> public Vector3D IntersectSlow(Line3D curve) { double x0 = Start.X, y0 = Start.Y, z0 = Start.Z, x1 = curve.Start.X, y1 = curve.Start.Y, z1 = curve.Start.Z, l0 = Direction.X, m0 = Direction.Y, n0 = Direction.Z, l1 = curve.Direction.X, m1 = curve.Direction.Y, n1 = curve.Direction.Z, deltaLM = l0 * m1 - m0 * l1, deltaMN = m0 * n1 - n0 * m1, deltaLN = l0 * n1 - n0 * l1, t0, t1; if (deltaLM.AreEqual(0) && deltaLN.AreEqual(0) && deltaMN.AreEqual(0)) { if (Start.IsOnTwoLine(this, curve) && !this.CoincidesWith(curve)) { return(Start); } if (End.IsOnTwoLine(this, curve) && !this.CoincidesWith(curve)) { return(End); } else { return(null); } } if (!deltaLM.AreEqual(0)) { t0 = (m1 * x1 - l1 * y1 - m1 * x0 + l1 * y0) / deltaLM; if (!l1.AreEqual(0)) { t1 = (x0 + l0 * t0 - x1) / l1; } else { t1 = (y0 + m0 * t0 - y1) / m1; } double zTry1 = z0 + n0 * t0, zTry2 = z1 + n1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (zTry1.AreEqual(zTry2) && intersection.IsOnTwoLine(this, curve)) { return(intersection); } else { return(null); } } else if (!deltaLN.AreEqual(0)) { t0 = (n1 * x1 - l1 * z1 - n1 * x0 + l1 * z0) / deltaLN; if (!l1.AreEqual(0)) { t1 = (x0 + l0 * t0 - x1) / l1; } else { t1 = (z0 + n0 * t0 - z1) / n1; } double yTry1 = y0 + m0 * t0, yTry2 = y1 + m1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (yTry1.AreEqual(yTry2) && intersection.IsOnTwoLine(this, curve)) { return(intersection); } else { return(null); } } else { t0 = (n1 * y1 - m1 * z1 - n1 * y0 + m1 * z0) / deltaMN; if (!m1.AreEqual(0)) { t1 = (y0 + m0 * t0 - y1) / m1; } else { t1 = (z0 + n0 * t0 - z1) / n1; } double xTry1 = x0 + l0 * t0, xTry2 = x1 + l1 * t1; Vector3D intersection = new Vector3D(x0 + l0 * t0, y0 + m0 * t0, z0 + n0 * t0); if (xTry1.AreEqual(xTry2) && intersection.IsOnTwoLine(this, curve)) { return(intersection); } else { return(null); } } }
/// <summary> /// 通过直线和多边形交点的奇偶性,获得相交的线段 /// </summary> /// <param name="intersectPoints"></param> /// <param name="faceEdges"></param> /// <returns></returns> private List <Line3D> GetLinesFromIntersectPoints(List <Vector3D> intersectPoints, List <Line3D> faceEdges) { List <Line3D> interLines = new List <Line3D>(); List <Vector3D> tempIntersectPoints = new List <Vector3D>(); foreach (var point in intersectPoints) { if (tempIntersectPoints.Contains(point, new Vector3DEqualityComparer())) { continue; } tempIntersectPoints.Add(point); } tempIntersectPoints = tempIntersectPoints.OrderByXYZ(); List <Vector3D> newIntersectPoints = new List <Vector3D>(tempIntersectPoints); bool firstPointIsEndPoint = false;//起点是否线的端点 for (int i = 0; i < newIntersectPoints.Count; i++) { bool isEndPoint = PointIsEndPointOfCurves(newIntersectPoints[i], faceEdges); if (i == 0 && isEndPoint) { firstPointIsEndPoint = true; } if (isEndPoint) { Vector3D newPoint = new Vector3D(newIntersectPoints[i].X, newIntersectPoints[i].Y, newIntersectPoints[i].Z); newIntersectPoints.Insert(i, newPoint); i++; } } if (firstPointIsEndPoint) { //取偶数线段 for (int i = 0; i < newIntersectPoints.Count - 1; i++) { if (i % 2 != 0) { if (newIntersectPoints[i].IsAlmostEqualTo(newIntersectPoints[i + 1])) { continue; } Line3D temp = new Line3D(newIntersectPoints[i], newIntersectPoints[i + 1]); interLines.Add(temp); } } } else { //取奇数线段 for (int i = 0; i < newIntersectPoints.Count - 1; i++) { if (i % 2 == 0) { if (newIntersectPoints[i].IsAlmostEqualTo(newIntersectPoints[i + 1])) { continue; } Line3D temp = new Line3D(newIntersectPoints[i], newIntersectPoints[i + 1]); interLines.Add(temp); } } } return(interLines); }
/// <summary> /// 有限面相交获得相交线段集合 /// </summary> /// <param name="source">与之相交的面</param> /// <returns></returns> public List <Line3D> Intersect(Face source) { Line3D intersectStratightLine = IntersectUnlimitedFace(source); if (intersectStratightLine == null) { return(new List <Line3D>()); } List <Line3D> originalEdges = this.Edges; List <Line3D> sourceEdges = source.Edges; //直线与多边形相交的交点 List <Vector3D> originalFaceInterPoint = new List <Vector3D>(); List <Vector3D> sourceFaceInterpoint = new List <Vector3D>(); foreach (var edge in originalEdges) { Vector3D intersectPoint = intersectStratightLine.IntersectStraightLine2(edge); if (intersectPoint != null) { originalFaceInterPoint.Add(intersectPoint); } } foreach (var edge in sourceEdges) { Vector3D intersectPoint = intersectStratightLine.IntersectStraightLine2(edge); if (intersectPoint != null) { sourceFaceInterpoint.Add(intersectPoint); } } if (originalFaceInterPoint.Count == 0 || sourceFaceInterpoint.Count == 0) { return(new List <Line3D>()); } //直线与多边形相交的交线 List <Line3D> originalFaceInterLine = GetLinesFromIntersectPoints(originalFaceInterPoint, originalEdges); List <Line3D> sourceFaceInterLine = GetLinesFromIntersectPoints(sourceFaceInterpoint, sourceEdges); //List<Line3D> originalFaceInterLine = GetLinesFromIntersectPoints2(originalFaceInterPoint, originalEdges); //List<Line3D> sourceFaceInterLine = GetLinesFromIntersectPoints2(sourceFaceInterpoint, sourceEdges); Merge(originalFaceInterLine); Merge(sourceFaceInterLine); //两个面所有的共有交线 List <Line3D> coownInterLine = new List <Line3D>(); foreach (var line1 in originalFaceInterLine) { foreach (var line2 in sourceFaceInterLine) { Line3D tempLine = GetPublicLine(line1, line2); if (tempLine != null) { coownInterLine.Add(tempLine); } } } return(coownInterLine); }