Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }