/// <summary> /// Performs a brute-force comparison of every segment in each <see cref="ISegmentString" />. /// This has n^2 performance. /// </summary> /// <param name="e0"></param> /// <param name="e1"></param> private void ComputeVertexSnaps(INodableSegmentString e0, INodableSegmentString e1) { Coordinate[] pts0 = e0.Coordinates; Coordinate[] pts1 = e1.Coordinates; for (int i0 = 0; i0 < pts0.Length - 1; i0++) { HotPixel hotPixel = new HotPixel(pts0[i0], _scaleFactor, _li); for (int i1 = 0; i1 < pts1.Length - 1; i1++) { // don't snap a vertex to itself if (e0 == e1) { if (i0 == i1) { continue; } } bool isNodeAdded = //AddSnappedNode(hotPixel, e1, i1); hotPixel.AddSnappedNode(e1, i1); // if a node is created for a vertex, that vertex must be noded too if (isNodeAdded) { e0.AddIntersection(pts0[i0], i0); } } } }
/// <summary> /// Adds a point as a Hot Pixel. <br/> /// If the point has been added already, it is marked as a node. /// </summary> /// <param name="p">The point to add</param> /// <returns>The hot-pixel for the point</returns> public HotPixel Add(Coordinate p) { // TODO: is there a faster way of doing this? var pRound = Round(p); var hp = Find(pRound); /* * Hot Pixels which are added more than once * must have more than one vertex in them * and thus must be nodes. */ if (hp != null) { hp.IsNode = true; return(hp); } /* * A pixel containing the point was not found, so create a new one. * It is initially set to NOT be a node * (but may become one later on). */ hp = new HotPixel(pRound, _scaleFactor); _index.Insert(hp.Coordinate, hp); return(hp); }
/// <summary> /// Snaps (nodes) all interacting segments to this hot pixel. /// The hot pixel may represent a vertex of an edge, /// in which case this routine uses the optimization /// of not noding the vertex itself /// </summary> /// <param name="hotPixel">The hot pixel to snap to.</param> /// <param name="parentEdge">The edge containing the vertex, if applicable, or <c>null</c>.</param> /// <param name="hotPixelVertexIndex"></param> /// <returns><c>true</c> if a node was added for this pixel.</returns> public bool Snap(HotPixel hotPixel, ISegmentString parentEdge, int hotPixelVertexIndex) { var pixelEnv = hotPixel.GetSafeEnvelope(); var hotPixelSnapAction = new HotPixelSnapAction(hotPixel, parentEdge, hotPixelVertexIndex); _index.Query(pixelEnv, new QueryVisitor(pixelEnv, hotPixelSnapAction)); return(hotPixelSnapAction.IsNodeAdded); }
/// <summary> /// Snaps segments to nodes created by segment intersections. /// </summary> /// <param name="snapPts"></param> private void ComputeIntersectionSnaps(IEnumerable <Coordinate> snapPts) { foreach (var snapPt in snapPts) { var hotPixel = new HotPixel(snapPt, _scaleFactor, _li); _pointSnapper.Snap(hotPixel); } }
/// <summary> /// Returns a "safe" envelope that is guaranteed to contain the hot pixel. /// The envelope returned is larger than the exact envelope of the /// pixel by a safe margin. /// </summary> /// <returns>An envelope which contains the hot pixel</returns> private Envelope GetSafeEnvelope(HotPixel hp) { double safeTolerance = SafeEnvExpansionFactor / hp.ScaleFactor; var safeEnv = new Envelope(hp.Coordinate); safeEnv.ExpandBy(safeTolerance); return(safeEnv); }
private HotPixel CreateHotPixel(Coordinate p) { if (_hotPixelMap.TryGetValue(p, out var hp)) { return(hp); } hp = new HotPixel(p, _scaleFactor); _hotPixelMap.Add(p, hp); return(hp); }
/// <summary> /// /// </summary> /// <param name="ss"></param> /// <param name="snapPts"></param> private void ComputeSnaps(INodableSegmentString ss, IEnumerable <Coordinate> snapPts) { foreach (Coordinate snapPt in snapPts) { HotPixel hotPixel = new HotPixel(snapPt, _scaleFactor, _li); for (int i = 0; i < ss.Count - 1; i++) { //AddSnappedNode(hotPixel, ss, i); hotPixel.AddSnappedNode(ss, i); } } }
/// <summary> /// Snaps segments to the vertices of a Segment String. /// </summary> /// <param name="e"></param> private void ComputeVertexSnaps(INodableSegmentString e) { var pts0 = e.Coordinates; for (var i = 0; i < pts0.Length; i++) { var hotPixel = new HotPixel(pts0[i], _scaleFactor, _li); var isNodeAdded = _pointSnapper.Snap(hotPixel, e, i); // if a node is created for a vertex, that vertex must be noded too if (isNodeAdded) { e.AddIntersection(pts0[i], i); } } }
/// <summary> /// Adds a new node (equal to the snap pt) to the specified segment /// if the segment passes through the hot pixel /// </summary> /// <returns><see langword="true"/> if a node was added to the segment</returns> private bool AddSnappedNode(HotPixel hotPixel, INodableSegmentString segStr, int segIndex ) { var coords = segStr.Coordinates; var p0 = coords[segIndex]; var p1 = coords[segIndex + 1]; if (hotPixel.Intersects(p0, p1)) { //System.out.println("snapped: " + snapPt); //System.out.println("POINT (" + snapPt.x + " " + snapPt.y + ")"); segStr.AddIntersection(hotPixel.Coordinate, segIndex); return(true); } return(false); }
/// <summary> /// Snaps (nodes) all interacting segments to this hot pixel. /// The hot pixel may represent a vertex of an edge, /// in which case this routine uses the optimization /// of not noding the vertex itself /// </summary> /// <param name="hotPixel">The hot pixel to snap to.</param> /// <returns><c>true</c> if a node was added for this pixel.</returns> public bool Snap(HotPixel hotPixel) { return(Snap(hotPixel, null, -1)); }
/// <summary> /// Initializes a new instance of the <see cref="HotPixelSnapAction"/> class. /// </summary> /// <param name="hotPixel"></param> /// <param name="parentEdge"></param> /// <param name="hotPixelVertexIndex"></param> public HotPixelSnapAction(HotPixel hotPixel, ISegmentString parentEdge, int hotPixelVertexIndex) { _hotPixel = hotPixel; _parentEdge = parentEdge; _hotPixelVertexIndex = hotPixelVertexIndex; }
/// <summary> /// Snaps segments to nodes created by segment intersections. /// </summary> /// <param name="snapPts"></param> private void ComputeIntersectionSnaps(IEnumerable<Coordinate> snapPts) { foreach (var snapPt in snapPts) { var hotPixel = new HotPixel(snapPt, _scaleFactor, _li); _pointSnapper.Snap(hotPixel); } }
/// <summary> /// Snaps segments to the vertices of a Segment String. /// </summary> /// <param name="e"></param> private void ComputeVertexSnaps(INodableSegmentString e) { var pts0 = e.Coordinates; for (var i = 0; i < pts0.Length; i++) { var hotPixel = new HotPixel(pts0[i], _scaleFactor, _li); var isNodeAdded = _pointSnapper.Snap(hotPixel, e, i); // if a node is created for a vertex, that vertex must be noded too if (isNodeAdded) e.AddIntersection(pts0[i], i); } }
/// <summary> /// Performs a brute-force comparison of every segment in each <see cref="ISegmentString" />. /// This has n^2 performance. /// </summary> /// <param name="e0"></param> /// <param name="e1"></param> private void ComputeVertexSnaps(INodableSegmentString e0, INodableSegmentString e1) { Coordinate[] pts0 = e0.Coordinates; Coordinate[] pts1 = e1.Coordinates; for (int i0 = 0; i0 < pts0.Length - 1; i0++) { HotPixel hotPixel = new HotPixel(pts0[i0], _scaleFactor, _li); for (int i1 = 0; i1 < pts1.Length - 1; i1++) { // don't snap a vertex to itself if (e0 == e1) if (i0 == i1) continue; bool isNodeAdded = //AddSnappedNode(hotPixel, e1, i1); hotPixel.AddSnappedNode(e1, i1); // if a node is created for a vertex, that vertex must be noded too if (isNodeAdded) e0.AddIntersection(pts0[i0], i0); } } }
/// <summary> /// /// </summary> /// <param name="ss"></param> /// <param name="snapPts"></param> private void ComputeSnaps(INodableSegmentString ss, IEnumerable<Coordinate> snapPts) { foreach (Coordinate snapPt in snapPts) { HotPixel hotPixel = new HotPixel(snapPt, _scaleFactor, _li); for (int i = 0; i < ss.Count - 1; i++) //AddSnappedNode(hotPixel, ss, i); hotPixel.AddSnappedNode(ss, i); } }