Example #1
0
        /// <summary>
        /// Gets whether a given point is inside a triangle
        /// </summary>
        /// <param name="p">Point</param>
        /// <param name="triangle">Triangle defined by 3 points</param>
        /// <returns>True if the point is inside given triangle</returns>
        public static bool IsPointInTriangle(Point3D p, Tuple <Point3D, Point3D, Point3D> triangle)
        {
            // taken from http://www.blackpawn.com/texts/pointinpoly/default.html

            // Compute vectors
            Point3D a = triangle.Item1;
            Point3D b = triangle.Item2;
            Point3D c = triangle.Item3;

            Point3D v0 = c - a;
            Point3D v1 = b - a;
            Point3D v2 = p - a;

            // Compute dot products
            float dot00 = v0.DotProduct(v0);
            float dot01 = v0.DotProduct(v1);
            float dot02 = v0.DotProduct(v2);
            float dot11 = v1.DotProduct(v1);
            float dot12 = v1.DotProduct(v2);

            // Compute barycentric coordinates
            double invDenom = 1F / (dot00 * dot11 - dot01 * dot01);
            double u        = (dot11 * dot02 - dot01 * dot12) * invDenom;
            double v        = (dot00 * dot12 - dot01 * dot02) * invDenom;

            // Check if point is in triangle
            return((u >= 0) && (v >= 0) && (u + v <= 1));
        }
Example #2
0
        /// <summary>
        /// Gets the line fragment intersection with a triangle (if any).
        /// </summary>
        /// <param name="triangle">Triangle defined by 3 points</param>
        /// <param name="line">Line fragment defined by 2 points</param>
        /// <returns>First item = 0 --> no intersetion; first item = 1 --> one
        /// intersection in the second item; first item = 2 --> line is on the
        /// plane</returns>
        public static Tuple <int, Point3D> GetTriangleIntersection(Tuple <Point3D, Point3D, Point3D> triangle, Vector3D line)
        {
#if DIAG
            _IntersectCounter++;
#endif

            Point3D vU1U2 = line.Point2 - line.Point1;
            Point3D vU1P1 = triangle.Item2 - line.Point1;
            Point3D norm  = GetPlanesNormal(triangle);

            float lenNormU1U2 = norm.DotProduct(vU1U2);
            float lenNormU1P1 = norm.DotProduct(vU1P1);

            // normala dotProduct usecka  =>  kdyz je to 0, jsou kolme, normala je kolma na plochu, tedy usecka a plocha jsou paralelni
            if (lenNormU1U2.EqEps(0))
            {
                if (lenNormU1P1.EqEps(0))
                {
                    // usecka lezi v rovine definovane trojuhelnikem.... detekuj si prunik usecky strojuhelnikem sam :-)
                    return(Tuple.Create <int, Point3D>(2, null));
                }
                else
                {
                    // usecka je paralelni s rovinou, takze nic se nikdy neprotne
                    return(Tuple.Create <int, Point3D>(0, null));
                }
            }

            // 0 zacatek, 1 konec usecky... uzavreny interval [0;1] == na usecce :-)
            float position = lenNormU1P1 / lenNormU1U2;

            if (0 <= position && position <= 1)
            {
                // ha!, usecka protina rovinu definovanou trojuhelnikem.... ted jen zjistit jestli ten bod je v tom trojuhelniku
                // měla by platit rovnost pro všechny 4 body roviny:
                // NBx = ZjistiNormaluPlochuDefinovanouTremiBodyVole(plocha)
                // NBx.Item1.DotProduct( [ plocha.Item1 ...až plocha.Item3 a bodPruniku] ) == NBx.Item3
                // jestli ne, mám něco blbě, což by nebylo nic zvláštního :)
                Point3D intersection = line.Point1 + vU1U2 * position;
                if (IsPointInTriangle(intersection, triangle))
                {
                    return(Tuple.Create(1, intersection));
                }
                return(Tuple.Create <int, Point3D>(0, null));
            }
            // usecka NEprotina plochu, ale kdybys ji prodlouzil (kdyby to byla primka), tak by rovinu protnula v bode (usecka.Item1 + vU1U2 * pozice)
            return(Tuple.Create <int, Point3D>(0, null));
        }