/// <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(); }
/// <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()); }
/// <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)); }
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); } }
/* * 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; }