/// <summary> /// check whether 2 vectors are parallel /// </summary> /// <param name="vec4A"> /// the vector to be checked /// </param> /// <param name="vec4B"> /// the vector to be checked /// </param> /// <returns> /// if they're parallel, return true; otherwise false /// </returns> private bool IsLinesParallel(Utility.Vector4 vec4A, Utility.Vector4 vec4B) { // if 2 vectors are parallel, they should be like the following formula: // vec4A.X vec4A.Y vec4A.Z // ------- == ------- == ------- // vec4B.X vec4B.Y vec4B.Z // change to multiply, it's // vec4A.X * vec4B.Y == vec4A.Y * vec4B.X && // vec4A.Y * vec4B.Z == vec4A.Z * vec4B.Y double aa = vec4A.X * vec4B.Y; double bb = vec4A.Y * vec4B.X; double cc = vec4A.Y * vec4B.Z; double dd = vec4A.Z * vec4B.Y; double ee = vec4A.X * vec4B.Z; double ff = vec4A.Z * vec4B.X; const double tolerance = 0.0001d; if (Math.Abs(aa - bb) < tolerance && Math.Abs(cc - dd) < tolerance && Math.Abs(ee - ff) < tolerance) { return(true); } return(false); }
/// <summary> /// compute the cross product of 2 edges /// </summary> /// <param name="edgeA"> /// the edge for the cross product /// </param> /// <param name="edgeB"> /// the edge for the cross product /// </param> /// <returns> /// the cross product of 2 edges /// </returns> private Utility.Vector4 ComputeCrossProduct(Edge edgeA, Edge edgeB) { List <XYZ> pointsA = edgeA.Tessellate() as List <XYZ>; List <XYZ> pointsB = edgeB.Tessellate() as List <XYZ>; Autodesk.Revit.DB.XYZ vectorA = pointsA[1] - pointsA[0]; Autodesk.Revit.DB.XYZ vectorB = pointsB[1] - pointsB[0]; Utility.Vector4 vec4A = new Utility.Vector4(vectorA); Utility.Vector4 vec4B = new Utility.Vector4(vectorB); return(Utility.Vector4.CrossProduct(vec4A, vec4B)); }
/// <summary> /// check whether 2 edges are parallel /// </summary> /// <param name="edgeA"> /// the edge to be checked /// </param> /// <param name="edgeB"> /// the edge to be checked /// </param> /// <returns> /// if they're parallel, return true; otherwise false /// </returns> private bool IsLinesParallel(Edge edgeA, Edge edgeB) { List <XYZ> pointsA = edgeA.Tessellate() as List <XYZ>; List <XYZ> pointsB = edgeB.Tessellate() as List <XYZ>; Autodesk.Revit.DB.XYZ vectorA = pointsA[1] - pointsA[0]; Autodesk.Revit.DB.XYZ vectorB = pointsB[1] - pointsB[0]; Utility.Vector4 vec4A = new Utility.Vector4(vectorA); Utility.Vector4 vec4B = new Utility.Vector4(vectorB); return(IsLinesParallel(vec4A, vec4B)); }
/// <summary> /// check whether the faces of the mass are one-one parallel /// </summary> /// <param name="faces"> /// the 6 faces of the mass /// </param> /// <returns> /// if the 6 faces are one-one parallel, return true; otherwise false /// </returns> private bool IsFacesParallel(FaceArray faces) { // step1: get the normals of the 6 faces List <Utility.Vector4> normals = new List <Utility.Vector4>(); foreach (Face face in faces) { EdgeArrayArray edgeArrayArray = face.EdgeLoops; EdgeArray edges = edgeArrayArray.get_Item(0); if (null == edges || 2 > edges.Size) { return(false); } // we use the cross product of 2 non-parallel vectors as the normal for (int i = 0; i < edges.Size - 1; i++) { Edge edgeA = edges.get_Item(i); Edge edgeB = edges.get_Item(i + 1); // if edgeA & edgeB are parallel, can't compute the cross product bool isLinesParallel = IsLinesParallel(edgeA, edgeB); if (true == isLinesParallel) { continue; } Utility.Vector4 vec4 = ComputeCrossProduct(edgeA, edgeB); normals.Add(vec4); break; } } // step 2: the 6 normals should be one-one parallel pairs if (null == normals || 6 != normals.Count) { return(false); } bool[] matchedList = new bool[6]; for (int i = 0; i < matchedList.Length; i++) { matchedList[i] = false; } // check whether the normal has another matched parallel normal for (int i = 0; i < matchedList.Length; i++) { if (true == matchedList[i]) { continue; } Utility.Vector4 vec4A = normals[i]; for (int j = 0; j < matchedList.Length; j++) { if (j == i || true == matchedList[j]) { continue; } Utility.Vector4 vec4B = normals[j]; if (true == IsLinesParallel(vec4A, vec4B)) { matchedList[i] = true; matchedList[j] = true; break; } } } // step 3: check each of the 6 normals has matched parallel normal for (int i = 0; i < matchedList.Length; i++) { if (false == matchedList[i]) { return(false); } } // all the normals have matched parallel normals return(true); }
/// <summary> /// check whether 2 edges are parallel /// </summary> /// <param name="edgeA"> /// the edge to be checked /// </param> /// <param name="edgeB"> /// the edge to be checked /// </param> /// <returns> /// if they're parallel, return true; otherwise false /// </returns> private bool IsLinesParallel(Edge edgeA, Edge edgeB) { List<XYZ> pointsA = edgeA.Tessellate() as List<XYZ>; List<XYZ> pointsB = edgeB.Tessellate() as List<XYZ>; Autodesk.Revit.DB.XYZ vectorA = pointsA[1] - pointsA[0]; Autodesk.Revit.DB.XYZ vectorB = pointsB[1] - pointsB[0]; Utility.Vector4 vec4A = new Utility.Vector4(vectorA); Utility.Vector4 vec4B = new Utility.Vector4(vectorB); return IsLinesParallel(vec4A, vec4B); }
/// <summary> /// compute the cross product of 2 edges /// </summary> /// <param name="edgeA"> /// the edge for the cross product /// </param> /// <param name="edgeB"> /// the edge for the cross product /// </param> /// <returns> /// the cross product of 2 edges /// </returns> private Utility.Vector4 ComputeCrossProduct(Edge edgeA, Edge edgeB) { List<XYZ> pointsA = edgeA.Tessellate() as List<XYZ>; List<XYZ> pointsB = edgeB.Tessellate() as List<XYZ>; Autodesk.Revit.DB.XYZ vectorA = pointsA[1] - pointsA[0]; Autodesk.Revit.DB.XYZ vectorB = pointsB[1] - pointsB[0]; Utility.Vector4 vec4A = new Utility.Vector4(vectorA); Utility.Vector4 vec4B = new Utility.Vector4(vectorB); return Utility.Vector4.CrossProduct(vec4A, vec4B); }