/// <summary>
        /// Gets the Voronoi cell around a site specified
        /// by the origin of a QuadEdge.
        /// </summary>
        /// <remarks>
        /// The userData of the polygon is set to be the <see cref="Coordinate" />
        /// of the site.  This allows attaching external
        /// data associated with the site to this cell polygon.
        /// </remarks>
        /// <param name="qe">a quadedge originating at the cell site</param>
        /// <param name="geomFact">a factory for building the polygon</param>
        /// <returns>a polygon indicating the cell extent</returns>
        public Polygon GetVoronoiCellPolygon(QuadEdge qe, GeometryFactory geomFact)
        {
            var cellPts = new List <Coordinate>();
            var startQE = qe;

            do
            {
                // Coordinate cc = circumcentre(qe);
                // use previously computed circumcentre
                var cc = qe.Rot.Orig.Coordinate;
                cellPts.Add(cc);

                // move to next triangle CW around vertex
                qe = qe.OPrev;
            } while (qe != startQE);

            var coordList = new CoordinateList();

            coordList.AddAll(cellPts, false);
            coordList.CloseRing();

            if (coordList.Count < 4)
            {
                Debug.WriteLine(coordList);
                coordList.Add(coordList[coordList.Count - 1], true);
            }

            var pts      = coordList.ToCoordinateArray();
            var cellPoly = geomFact.CreatePolygon(geomFact.CreateLinearRing(pts));

            var v = startQE.Orig;

            cellPoly.UserData = v.Coordinate;
            return(cellPoly);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputPts"></param>
        /// <returns></returns>
        private static Coordinate[] ComputeOctRing(Coordinate[] inputPts)
        {
            var octPts = ComputeOctPts(inputPts);
            var coordList = new CoordinateList();
            coordList.Add(octPts, false);

            // points must all lie in a line
            if (coordList.Count < 3)
                return null;
            
            coordList.CloseRing();
            return coordList.ToCoordinateArray();
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="inputPts"></param>
        /// <returns></returns>
        private ICoordinate[] ComputeOctRing(ICoordinate[] inputPts)
        {
            ICoordinate[]  octPts    = ComputeOctPts(inputPts);
            CoordinateList coordList = new CoordinateList();

            coordList.Add(octPts, false);

            // points must all lie in a line
            if (coordList.Count < 3)
            {
                return(null);
            }

            coordList.CloseRing();
            return(coordList.ToCoordinateArray());
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="inputPts"></param>
        /// <returns></returns>
        private static Coordinate[] ComputeOctRing(Coordinate[] inputPts)
        {
            Coordinate[]   octPts    = ComputeOctPts(inputPts);
            CoordinateList coordList = new CoordinateList {
                { octPts, false }
            };

            // points must all lie in a line
            if (coordList.Count < 3)
            {
                return(null);
            }

            coordList.CloseRing();
            return(coordList.ToCoordinateArray());
        }
        public static Geometry LineToPolygon(Geometry g)
        {
            if (g is IPolygonal)
            {
                return(g);
            }
            // TODO: ensure ring is valid
            var ringList = new CoordinateList();
            var pts      = g.Coordinates;

            foreach (var pt in pts)
            {
                ringList.Add(pt, true);
            }
            ringList.CloseRing();
            var ring = g.Factory.CreateLinearRing(ringList.ToCoordinateArray());

            return(g.Factory.CreatePolygon(ring, null));
        }
示例#6
0
        private Coordinate[] GetBoundary(int level, Coordinate origin, double width)
        {
            double y = origin.Y;

            // for all levels beyond 0 need to vertically shift shape by height of one "arm" to centre it
            if (level > 0)
            {
                y += ThirdHeight * width;
            }

            var p0 = new Coordinate(origin.X, y);
            var p1 = new Coordinate(origin.X + width / 2, y + width * HeightFactor);
            var p2 = new Coordinate(origin.X + width, y);

            AddSide(level, p0, p1);
            AddSide(level, p1, p2);
            AddSide(level, p2, p0);
            _coordList.CloseRing();
            return(_coordList.ToCoordinateArray());
        }
            public void Visit(QuadEdge[] triEdges)
            {
                _coordList.Clear();
                for (int i = 0; i < 3; i++)
                {
                    var v = triEdges[i].Orig;
                    _coordList.Add(v.Coordinate);
                }
                if (_coordList.Count > 0)
                {
                    _coordList.CloseRing();
                    var pts = _coordList.ToCoordinateArray();
                    if (pts.Length != 4)
                    {
                        //CheckTriangleSize(pts);
                        return;
                    }

                    _triCoords.Add(pts);
                }
            }
示例#8
0
        /*
         * private bool IsInsideEdge(Envelope env, int edgeIndex)
         * {
         *  switch (edgeIndex)
         *  {
         *      case ENV_BOTTOM:
         *          return env.MinY > _clipEnvMinY;
         *      case ENV_RIGHT:
         *          return env.MaxX < _clipEnvMaxX;
         *      case ENV_TOP:
         *          return env.MaxY < _clipEnvMaxY;
         *      case ENV_LEFT:
         *      default:
         *          return env.MinX > _clipEnvMinX;
         *  }
         * }
         *
         * private bool IsOutsideEdge(Envelope env, int edgeIndex)
         * {
         *  switch (edgeIndex)
         *  {
         *      case ENV_BOTTOM:
         *          return env.MaxY < _clipEnvMinY;
         *      case ENV_RIGHT:
         *          return env.MinX > _clipEnvMaxX;
         *      case ENV_TOP:
         *          return env.MinY > _clipEnvMaxY;
         *      case ENV_LEFT:
         *      default:
         *          return env.MaxX < _clipEnvMinX;
         *  }
         * }
         *
         * Envelope currentCoordsEnv;
         */

        /// <summary>
        /// Clips ring to a axis-parallel line defined by a single box edge.
        /// </summary>
        /// <param name="coords">An array of coordinates</param>
        /// <param name="edgeIndex">An edge index</param>
        /// <returns>The clipped points, or <c>null</c> if all were clipped</returns>
        private Coordinate[] ClipRingToBoxEdge(Coordinate[] coords, int edgeIndex)
        {
            var clipCoords = new CoordinateList();

            var p0 = coords[coords.Length - 1];

            for (int i = 0; i < coords.Length; i++)
            {
                var p1 = coords[i];
                if (IsInsideEdge(p1, edgeIndex))
                {
                    if (!IsInsideEdge(p0, edgeIndex))
                    {
                        var intPt = IntersectionPrecise(p0, p1, edgeIndex);
                        clipCoords.Add(intPt, false);
                        //currentCoordsEnv.expandToInclude(intPt);
                    }
                    // TODO: avoid copying so much?
                    var p1Precise = MakePrecise(p1.Copy());
                    clipCoords.Add(p1Precise, false);
                    //currentCoordsEnv.expandToInclude(p1Precise);
                }
                else if (IsInsideEdge(p0, edgeIndex))
                {
                    var intPt = IntersectionPrecise(p0, p1, edgeIndex);
                    clipCoords.Add(intPt, false);
                    //currentCoordsEnv.expandToInclude(intPt);
                }
                // move to next segment
                p0 = p1;
            }
            // check if all points clipped off
            if (clipCoords.Count <= 0)
            {
                return(null);
            }

            clipCoords.CloseRing();
            return(clipCoords.ToCoordinateArray());
        }
        /// <summary>
        /// Gets the Voronoi cell around a site specified
        /// by the origin of a QuadEdge.
        /// </summary>
        /// <remarks>
        /// The userData of the polygon is set to be the <see cref="Coordinate" />
        /// of the site.  This allows attaching external
        /// data associated with the site to this cell polygon.
        /// </remarks>
        /// <param name="qe">a quadedge originating at the cell site</param>
        /// <param name="geomFact">a factory for building the polygon</param>
        /// <returns>a polygon indicating the cell extent</returns>
        public IPolygon GetVoronoiCellPolygon(QuadEdge qe, IGeometryFactory geomFact)
        {
            var cellPts = new List<Coordinate>();
            QuadEdge startQE = qe;

            do
            {
                // Coordinate cc = circumcentre(qe);
                // use previously computed circumcentre
                Coordinate cc = qe.Rot.Orig.Coordinate;
                cellPts.Add(cc);

                // move to next triangle CW around vertex
                qe = qe.OPrev;
            } while (qe != startQE);

            var coordList = new CoordinateList();
            coordList.AddAll(cellPts, false);
            coordList.CloseRing();

            if (coordList.Count < 4)
            {
            #if !PCL
                Debug.WriteLine(coordList);
            #endif
                coordList.Add(coordList[coordList.Count - 1], true);
            }

            Coordinate[] pts = coordList.ToCoordinateArray();
            IPolygon cellPoly = geomFact.CreatePolygon(geomFact.CreateLinearRing(pts), null);

            Vertex v = startQE.Orig;
            cellPoly.UserData = v.Coordinate;
            return cellPoly;
        }