示例#1
0
        public bool ContainsVertex(gVertex vertex)
        {
            gVertex maxVertex   = vertices.OrderByDescending(v => v.DistanceTo(vertex)).First();
            double  maxDistance = vertex.DistanceTo(maxVertex) * 1.5;
            gVertex v2          = gVertex.ByCoordinates(vertex.X + maxDistance, vertex.Y, vertex.Z);
            gEdge   ray         = gEdge.ByStartVertexEndVertex(vertex, v2);
            gVertex coincident  = null;
            int     windNumber  = 0;

            foreach (gEdge edge in edges)
            {
                gBase intersection = ray.Intersection(edge);
                if (edge.StartVertex.Y <= vertex.Y)
                {
                    if (edge.EndVertex.Y > vertex.Y && intersection != null && intersection.GetType() == typeof(gVertex))
                    {
                        ++windNumber;
                    }
                }
                else
                {
                    if (edge.EndVertex.Y <= vertex.Y && intersection != null && intersection.GetType() == typeof(gVertex))
                    {
                        --windNumber;
                    }
                }
            }

            //If intersections is odd, returns true, false otherwise
            //return (intersections % 2 == 0) ? false : true;
            return(windNumber != 0);
        }
示例#2
0
        internal gPolygon AddVertex(gVertex v, gEdge intersectingEdge)
        {
            //Assumes that vertex v intersects one of polygons edges.
            gPolygon newPolygon = (gPolygon)this.Clone();

            // Assign the polygon Id to the new vertex.
            v.polygonId = this.id;

            // Getting the index of the intersecting edge's start vertex and
            // inserting the new vertex at the following index.
            int index = newPolygon.vertices.IndexOf(intersectingEdge.StartVertex);

            newPolygon.vertices.Insert(index + 1, v);

            // Rebuilding edges.
            newPolygon.edges.Clear();
            int verticesCount = newPolygon.vertices.Count;

            for (var i = 0; i < verticesCount; i++)
            {
                int nextIndex = (i + 1) % verticesCount;
                newPolygon.edges.Add(new gEdge(newPolygon.vertices[i], newPolygon.vertices[nextIndex]));
            }

            return(newPolygon);
        }
示例#3
0
        public bool IsCoplanarTo(gEdge edge)
        {
            // http://mathworld.wolfram.com/Coplanar.html
            gVector a = this.Direction;
            gVector b = edge.Direction;
            gVector c = gVector.ByTwoVertices(this.StartVertex, edge.StartVertex);

            return(c.Dot(a.Cross(b)) == 0);
        }
示例#4
0
        public double DistanceTo(gEdge edge)
        {
            // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
            gVector v1          = gVector.ByTwoVertices(this, edge.StartVertex);
            gVector v2          = gVector.ByTwoVertices(this, edge.EndVertex);
            gVector numerator   = v1.Cross(v2);
            gVector denominator = gVector.ByTwoVertices(edge.EndVertex, edge.StartVertex);

            return(numerator.Length / denominator.Length);
        }
示例#5
0
 public bool Intersects(gEdge edge)
 {
     if (this.StartVertex.OnEdge(edge) || this.EndVertex.OnEdge(edge))
     {
         if (this.Direction.IsParallelTo(edge.Direction))
         {
             return(true);
         }
     }
     return(this.Intersection(edge) != null);
 }
示例#6
0
        //public Line AsLine()
        //{
        //    return Line.ByStartPointEndPoint(StartVertex.AsPoint(), EndVertex.AsPoint());
        //}

        #region override methods
        //TODO: Improve overriding equality methods as per http://www.loganfranken.com/blog/687/overriding-equals-in-c-part-1/

        /// <summary>
        /// Override of Equal Method
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            gEdge e = (gEdge)obj;

            if (StartVertex.Equals(e.StartVertex) && EndVertex.Equals(e.EndVertex))
            {
                return(true);
            }
            if (StartVertex.Equals(e.EndVertex) && EndVertex.Equals(e.StartVertex))
            {
                return(true);
            }
            return(false);
        }
示例#7
0
 public double DistanceTo(gEdge edge)
 {
     // http://mathworld.wolfram.com/Line-LineDistance.html
     if (this.IsCoplanarTo(edge))
     {
         var distances = new double[4] {
             StartVertex.DistanceTo(edge),
             EndVertex.DistanceTo(edge),
             edge.StartVertex.DistanceTo(this),
             edge.EndVertex.DistanceTo(this)
         };
         return(distances.Min());
     }
     else
     {
         var     a           = this.Direction;
         var     b           = edge.Direction;
         var     c           = gVector.ByTwoVertices(this.StartVertex, edge.StartVertex);
         gVector cross       = a.Cross(b);
         double  numerator   = c.Dot(cross);
         double  denominator = cross.Length;
         return(Math.Abs(numerator) / Math.Abs(denominator));
     }
 }
示例#8
0
        public gBase Intersection(gEdge edge)
        {
            // http://mathworld.wolfram.com/Line-LineIntersection.html
            if (!this.IsCoplanarTo(edge))
            {
                return(null);
            }
            if (edge.Contains(this.StartVertex))
            {
                return(StartVertex);
            }
            if (edge.Contains(this.EndVertex))
            {
                return(EndVertex);
            }

            var a   = this.Direction;
            var b   = edge.Direction;
            var c   = gVector.ByTwoVertices(this.StartVertex, edge.StartVertex);
            var cxb = c.Cross(b);
            var axb = a.Cross(b);
            var dot = cxb.Dot(axb);

            // if dot == 0 it means that they are parallels

            if (Threshold(dot, 0))
            {
                //Fully contains the test edge
                if (edge.StartVertex.OnEdge(this) && edge.EndVertex.OnEdge(this))
                {
                    return(edge);
                }
                else if (this.StartVertex.OnEdge(edge) || this.EndVertex.OnEdge(edge))
                {
                    gVertex[] vertices = new gVertex[4]
                    {
                        this.StartVertex,
                        this.EndVertex,
                        edge.StartVertex,
                        edge.EndVertex
                    };
                    var sorted = vertices.OrderBy(v => v.Y).ThenBy(v => v.X).ThenBy(v => v.Z).ToList();
                    return(gEdge.ByStartVertexEndVertex(sorted[1], sorted[2]));
                }
                else
                {
                    return(null);
                }
            }

            double s = (dot) / Math.Pow(axb.Length, 2);

            // s > 1, means that "intersection" vertex is not on either edge
            // s == NaN means they are parallels so never intersect
            if (s < 0 || s > 1 || Double.IsNaN(s))
            {
                return(null);
            }

            gVertex intersection = this.StartVertex.Translate(a.Scale(s));

            if (intersection.Equals(edge.StartVertex))
            {
                return(edge.StartVertex);
            }
            if (intersection.Equals(edge.EndVertex))
            {
                return(edge.EndVertex);
            }
            if (!intersection.OnEdge(edge))
            {
                return(null);
            }

            return(intersection);
        }
示例#9
0
 public bool OnEdge(gEdge edge)
 {
     return(this.OnEdge(edge.StartVertex, edge.EndVertex));
 }