Beispiel #1
0
        //Vertices need to be reduced to 2D
        //see Akenine-Möller, Tomas; Haines, Eric; Hoffman, Naty (2016): Real-Time Rendering, p. 754
        /// <summary>
        /// Tests if a point/vertex lies inside or outside a face - Only use this if you know the face AND vertex lie in the same plane and this plane is parallel to xy or xz or yz!
        /// </summary>
        /// <param name="geometry">The geometry the polygon (here: face) belongs to.</param>
        /// <param name="face">The faces to be tested. It will not be Reduced2D!</param>
        /// <param name="v">The vertex to be tested.</param>
        /// <returns></returns>
        public static bool IsPointInPolygon(this Geometry geometry, Face face, float3 v)
        {
            var inside    = false;
            var faceVerts = geometry.GetFaceVertices(face.Handle).ToList();

            var v1    = geometry.GetVertexByHandle(faceVerts.Last().Handle);
            var v1Pos = geometry.Get2DVertPos(face, v1.Handle);

            var y0 = v1Pos.y >= v.y;

            foreach (var vert in faceVerts)
            {
                var e1Pos = geometry.Get2DVertPos(face, vert.Handle);

                var y1 = e1Pos.y >= v.y;
                if (y0 != y1)
                {
                    if ((e1Pos.y - v.y) * (v1Pos.x - e1Pos.x) >=
                        (e1Pos.x - v.x) * (v1Pos.y - e1Pos.y) == y1)
                    {
                        inside = !inside;
                    }
                }
                y0    = y1;
                v1Pos = e1Pos;
            }
            return(inside);
        }
Beispiel #2
0
        private static bool IsPolygonRightOfVert(Geometry geometry, Face face, IList <HalfEdge> faceHalfEdges, Vertex vert)
        {
            var prevV = GetPrevVertex(face, faceHalfEdges, vert);
            var nextV = GetNextVertex(face, faceHalfEdges, vert);

            var redPrevPos = geometry.Get2DVertPos(face, prevV.Handle);
            var redNextPos = geometry.Get2DVertPos(face, nextV.Handle);

            return(redPrevPos.y > redNextPos.y);
        }
Beispiel #3
0
        //Vertices need to be reduced to 2D.
        /// <summary>
        /// Determines if the angle between two vectors, formed by three vertices, is greater or equal 180°.
        /// The first vector will be created from v1 and v2, the second from v2 and v3.
        /// </summary>
        /// <param name="geom">The geometry the vertices belong to.</param>
        /// <param name="face">The face the vertices belong to.</param>
        /// <param name="v1">Vertex one</param>
        /// <param name="v2">Vertex two</param>
        /// <param name="v3">Vertex three</param>
        /// <returns></returns>
        public static bool IsAngleGreaterOrEqualPi(this Geometry geom, Face face, Vertex v1, Vertex v2, Vertex v3)
        {
            var v1Pos = geom.Get2DVertPos(face, v1.Handle);
            var v2Pos = geom.Get2DVertPos(face, v2.Handle);
            var v3Pos = geom.Get2DVertPos(face, v3.Handle);

            var firstVec  = v1Pos - v2Pos;
            var secondVec = v3Pos - v2Pos;

            var cross = firstVec.x * secondVec.y - firstVec.y * secondVec.x; //Z component of the cross product.
            var dot   = float3.Dot(firstVec, secondVec);

            var angle = (float)System.Math.Atan2(cross, dot);

            return(angle <= 0);
        }
Beispiel #4
0
        //Vertices need to be reduced to 2D.
        /// <summary>
        /// Determines whether the angle between two vectors formed by three vertices is greater than 180 °.
        /// The first vector will be created from v1 and v2, the second from v2 and v3.
        /// </summary>
        /// <param name="geom">The geometry the vertices belong to.</param>
        /// <param name="face">The face the vertices belong to.</param>
        /// <param name="v1">Vertex one</param>
        /// <param name="v2">Vertex two</param>
        /// <param name="v3">Vertex three</param>
        /// <returns></returns>
        public static bool IsAngleGreaterPi(this Geometry geom, Face face, Vertex v1, Vertex v2, Vertex v3)
        {
            var v1Pos = geom.Get2DVertPos(face, v1.Handle);
            var v2Pos = geom.Get2DVertPos(face, v2.Handle);
            var v3Pos = geom.Get2DVertPos(face, v3.Handle);

            var firstVec  = v1Pos - v2Pos;
            var secondVec = v3Pos - v2Pos;

            var det = firstVec.x * secondVec.y - firstVec.y * secondVec.x; //determinant / Z component of the cross product / sine / y
            var dot = float3.Dot(firstVec, secondVec);                     // cosine / x

            var angle = (float)System.Math.Atan2(det, dot);

            if ((angle * -1).Equals(M.Pi))
            {
                return(false);
            }
            return(angle < 0);
        }
Beispiel #5
0
        //Vertices need to be reduced to 2D.
        private static IList <Vertex> GetSortedVertices(Geometry geometry, Face face, IEnumerable <Vertex> unsortedVerts)
        {
            var sorted = new List <Vertex>();

            sorted.AddRange(unsortedVerts);
            sorted.Sort(delegate(Vertex a, Vertex b)
            {
                var redA = geometry.Get2DVertPos(face, a.Handle);
                var redB = geometry.Get2DVertPos(face, b.Handle);

                var ydiff = -1 * redA.y.CompareTo(redB.y);
                if (ydiff != 0)
                {
                    return(ydiff);
                }

                return(redA.x.CompareTo(redB.x));
            });

            return(sorted);
        }
Beispiel #6
0
        //Vertices need to be reduced to 2D.
        private static bool IsUnderVert(Face face, Vertex middle, Vertex neighbour)
        {
            var redMiddle    = _geometry.Get2DVertPos(face, middle.Handle);
            var redNeighbour = _geometry.Get2DVertPos(face, neighbour.Handle);

            if (redMiddle.y > redNeighbour.y)
            {
                return(true);
            }
            if (redMiddle.y.Equals(redNeighbour.y) && redMiddle.x < redNeighbour.x)
            {
                return(true);
            }
            return(false);
        }