public static Vector4 FindTwoTetrahedronsSplittingPlane(Tetrahedron first, Tetrahedron second) { List<Vector3> potentialSplitPlanes = new List<Vector3>(); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[0].X, first.m_TetPlanes[0].Y, first.m_TetPlanes[0].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[1].X, first.m_TetPlanes[1].Y, first.m_TetPlanes[1].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[2].X, first.m_TetPlanes[2].Y, first.m_TetPlanes[2].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[3].X, first.m_TetPlanes[3].Y, first.m_TetPlanes[3].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[0].X, second.m_TetPlanes[0].Y, second.m_TetPlanes[0].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[1].X, second.m_TetPlanes[1].Y, second.m_TetPlanes[1].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[2].X, second.m_TetPlanes[2].Y, second.m_TetPlanes[2].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[3].X, second.m_TetPlanes[3].Y, second.m_TetPlanes[3].Z)); Vector3[] tetEdgeVectorsFirst = new Vector3[6]; Vector3[] tetEdgeVectorsSecond = new Vector3[6]; tetEdgeVectorsFirst[0] = first.m_Vertices[1] - first.m_Vertices[0]; tetEdgeVectorsFirst[1] = first.m_Vertices[2] - first.m_Vertices[0]; tetEdgeVectorsFirst[2] = first.m_Vertices[3] - first.m_Vertices[0]; tetEdgeVectorsFirst[3] = first.m_Vertices[2] - first.m_Vertices[1]; tetEdgeVectorsFirst[4] = first.m_Vertices[3] - first.m_Vertices[2]; tetEdgeVectorsFirst[5] = first.m_Vertices[1] - first.m_Vertices[3]; tetEdgeVectorsSecond[0] = second.m_Vertices[1] - second.m_Vertices[0]; tetEdgeVectorsSecond[1] = second.m_Vertices[2] - second.m_Vertices[0]; tetEdgeVectorsSecond[2] = second.m_Vertices[3] - second.m_Vertices[0]; tetEdgeVectorsSecond[3] = second.m_Vertices[2] - second.m_Vertices[1]; tetEdgeVectorsSecond[4] = second.m_Vertices[3] - second.m_Vertices[2]; tetEdgeVectorsSecond[5] = second.m_Vertices[1] - second.m_Vertices[3]; foreach (var tetEdgeFirst in tetEdgeVectorsFirst) { foreach (var tetEdgeSecond in tetEdgeVectorsSecond) { // Normal of plane constructed by those 2 edges var planeNormal = Vector3.Cross(tetEdgeFirst, tetEdgeSecond); if (planeNormal.LengthSquared() > 0.001f) { planeNormal.Normalize(); potentialSplitPlanes.Add(planeNormal); } } } const float epsilon = 0.001f;// fixed 1mm foreach (var splittingPlaneNormal in potentialSplitPlanes) { Vector2 tetOneLimits = GeometricsAlgorithms.GetAxisProjectionLimits(first.m_Vertices, splittingPlaneNormal); Vector2 tetTwoLimits = GeometricsAlgorithms.GetAxisProjectionLimits(second.m_Vertices, splittingPlaneNormal); if ((tetOneLimits.X + epsilon) > tetTwoLimits.Y) { return new Vector4(splittingPlaneNormal, -(tetOneLimits.X + tetTwoLimits.Y) / 2.0f); } if (tetOneLimits.Y < (tetTwoLimits.X + epsilon)) { return new Vector4(splittingPlaneNormal, -(tetOneLimits.Y + tetTwoLimits.X) / 2.0f); } } throw new Exception("no splitting plane found"); }
public static Vector4 FindTwoTetrahedronsSplittingPlane(Tetrahedron first, Tetrahedron second) { List <Vector3> potentialSplitPlanes = new List <Vector3>(); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[0].X, first.m_TetPlanes[0].Y, first.m_TetPlanes[0].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[1].X, first.m_TetPlanes[1].Y, first.m_TetPlanes[1].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[2].X, first.m_TetPlanes[2].Y, first.m_TetPlanes[2].Z)); potentialSplitPlanes.Add(new Vector3(first.m_TetPlanes[3].X, first.m_TetPlanes[3].Y, first.m_TetPlanes[3].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[0].X, second.m_TetPlanes[0].Y, second.m_TetPlanes[0].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[1].X, second.m_TetPlanes[1].Y, second.m_TetPlanes[1].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[2].X, second.m_TetPlanes[2].Y, second.m_TetPlanes[2].Z)); potentialSplitPlanes.Add(new Vector3(second.m_TetPlanes[3].X, second.m_TetPlanes[3].Y, second.m_TetPlanes[3].Z)); Vector3[] tetEdgeVectorsFirst = new Vector3[6]; Vector3[] tetEdgeVectorsSecond = new Vector3[6]; tetEdgeVectorsFirst[0] = first.m_Vertices[1] - first.m_Vertices[0]; tetEdgeVectorsFirst[1] = first.m_Vertices[2] - first.m_Vertices[0]; tetEdgeVectorsFirst[2] = first.m_Vertices[3] - first.m_Vertices[0]; tetEdgeVectorsFirst[3] = first.m_Vertices[2] - first.m_Vertices[1]; tetEdgeVectorsFirst[4] = first.m_Vertices[3] - first.m_Vertices[2]; tetEdgeVectorsFirst[5] = first.m_Vertices[1] - first.m_Vertices[3]; tetEdgeVectorsSecond[0] = second.m_Vertices[1] - second.m_Vertices[0]; tetEdgeVectorsSecond[1] = second.m_Vertices[2] - second.m_Vertices[0]; tetEdgeVectorsSecond[2] = second.m_Vertices[3] - second.m_Vertices[0]; tetEdgeVectorsSecond[3] = second.m_Vertices[2] - second.m_Vertices[1]; tetEdgeVectorsSecond[4] = second.m_Vertices[3] - second.m_Vertices[2]; tetEdgeVectorsSecond[5] = second.m_Vertices[1] - second.m_Vertices[3]; foreach (var tetEdgeFirst in tetEdgeVectorsFirst) { foreach (var tetEdgeSecond in tetEdgeVectorsSecond) { // Normal of plane constructed by those 2 edges var planeNormal = Vector3.Cross(tetEdgeFirst, tetEdgeSecond); if (planeNormal.LengthSquared() > 0.001f) { planeNormal.Normalize(); potentialSplitPlanes.Add(planeNormal); } } } const float epsilon = 0.001f;// fixed 1mm foreach (var splittingPlaneNormal in potentialSplitPlanes) { Vector2 tetOneLimits = GeometricsAlgorithms.GetAxisProjectionLimits(first.m_Vertices, splittingPlaneNormal); Vector2 tetTwoLimits = GeometricsAlgorithms.GetAxisProjectionLimits(second.m_Vertices, splittingPlaneNormal); if ((tetOneLimits.X + epsilon) > tetTwoLimits.Y) { return(new Vector4(splittingPlaneNormal, -(tetOneLimits.X + tetTwoLimits.Y) / 2.0f)); } if (tetOneLimits.Y < (tetTwoLimits.X + epsilon)) { return(new Vector4(splittingPlaneNormal, -(tetOneLimits.Y + tetTwoLimits.X) / 2.0f)); } } throw new Exception("no splitting plane found"); }