/// <summary> /// Clasifica un punto respecto de un Cuerpo Convexo de N caras. /// Puede devolver OUTSIDE o INSIDE (si es coincidente se considera como INSIDE). /// Los planos del Cuerpo Convexo deben apuntar hacia adentro. /// </summary> /// <param name="q">Punto a clasificar</param> /// <param name="polyhedron">Cuerpo Convexo</param> /// <returns>Resultado de la clasificación</returns> public static ConvexPolyhedronResult classifyPointConvexPolyhedron(Vector3 q, TgcConvexPolyhedron polyhedron) { bool fistTime = true; PointPlaneResult lastC = PointPlaneResult.BEHIND; PointPlaneResult c; for (int i = 0; i < polyhedron.Planes.Length; i++) { c = TgcCollisionUtils.classifyPointPlane(q, polyhedron.Planes[i]); if (c == PointPlaneResult.COINCIDENT) { continue; } //guardar clasif para primera vez if (fistTime) { fistTime = false; lastC = c; } //comparar con ultima clasif if (c != lastC) { //basta con que haya una distinta para que este Afuera return(ConvexPolyhedronResult.OUTSIDE); } } //Si todos dieron el mismo resultado, entonces esta adentro return(ConvexPolyhedronResult.INSIDE); }
/// <summary> /// Recorta un polígono convexo en 3D por un plano. /// Devuelve el nuevo polígono recortado. /// Algoritmo de Sutherland-Hodgman /// </summary> /// <param name="poly">Vértices del polígono a recortar</param> /// <param name="p">Plano con el cual se recorta</param> /// <param name="clippedPoly">Vértices del polígono recortado></param> /// <returns>True si el polígono recortado es válido. False si está degenerado</returns> public static bool clipConvexPolygon(Vector3[] polyVertices, Plane p, out Vector3[] clippedPolyVertices) { int thisInd = polyVertices.Length - 1; PointPlaneResult thisRes = classifyPointPlane(polyVertices[thisInd], p); List <Vector3> outVert = new List <Vector3>(polyVertices.Length); float t; for (int nextInd = 0; nextInd < polyVertices.Length; nextInd++) { PointPlaneResult nextRes = classifyPointPlane(polyVertices[nextInd], p); if (thisRes == PointPlaneResult.IN_FRONT_OF || thisRes == PointPlaneResult.COINCIDENT) { // Add the point outVert.Add(polyVertices[thisInd]); } if ((thisRes == PointPlaneResult.BEHIND && nextRes == PointPlaneResult.IN_FRONT_OF) || thisRes == PointPlaneResult.IN_FRONT_OF && nextRes == PointPlaneResult.BEHIND) { // Add the split point Vector3 q; intersectSegmentPlane(polyVertices[thisInd], polyVertices[nextInd], p, out t, out q); outVert.Add(q); } thisInd = nextInd; thisRes = nextRes; } //Polígono válido if (outVert.Count >= 3) { clippedPolyVertices = outVert.ToArray(); return(true); } //Polígono degenerado clippedPolyVertices = null; return(false); }