public override void OnMouseMove(ICoordinate worldPosition, MouseEventArgs e) { StartDrawing(); if (!isBusy) { // If the newNodeTool is active but not actual dragging a new 'Node' show the snap position. IPoint point = GeometryFactory.CreatePoint(worldPosition); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(Layer, null, point, worldPosition, -1); } else { IPoint point = GeometryFactory.CreatePoint(worldPosition); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(Layer, null, point, worldPosition, -1); if (snapResult != null) { newNode.Coordinates[0].X = snapResult.Location.X; newNode.Coordinates[0].Y = snapResult.Location.Y; newNodeLayer.Style = nodeStyle; } else { newNode.Coordinates[0].X = worldPosition.X; newNode.Coordinates[0].Y = worldPosition.Y; newNodeLayer.Style = errorNodeStyle; } } DoDrawing(true); StopDrawing(); }
/// <summary> /// Computes the "edge distance" of an intersection point p along a segment. /// The edge distance is a metric of the point along the edge. /// The metric used is a robust and easy to compute metric function. /// It is not equivalent to the usual Euclidean metric. /// It relies on the fact that either the x or the y ordinates of the /// points in the edge are unique, depending on whether the edge is longer in /// the horizontal or vertical direction. /// NOTE: This function may produce incorrect distances /// for inputs where p is not precisely on p1-p2 /// (E.g. p = (139,9) p1 = (139,10), p2 = (280,1) produces distanct 0.0, which is incorrect. /// My hypothesis is that the function is safe to use for points which are the /// result of rounding points which lie on the line, but not safe to use for truncated points. /// </summary> public static double ComputeEdgeDistance(ICoordinate p, ICoordinate p0, ICoordinate p1) { double dx = Math.Abs(p1.X - p0.X); double dy = Math.Abs(p1.Y - p0.Y); double dist = -1.0; // sentinel value if (p.Equals(p0)) dist = 0.0; else if (p.Equals(p1)) { if (dx > dy) dist = dx; else dist = dy; } else { double pdx = Math.Abs(p.X - p0.X); double pdy = Math.Abs(p.Y - p0.Y); if (dx > dy) dist = pdx; else dist = pdy; // <FIX>: hack to ensure that non-endpoints always have a non-zero distance if (dist == 0.0 && ! p.Equals(p0)) dist = Math.Max(pdx, pdy); } Assert.IsTrue(!(dist == 0.0 && ! p.Equals(p0)), "Bad distance calculation"); return dist; }
/// <summary> /// /// </summary> /// <returns></returns> public bool IsNonNested() { for (int i = 0; i < rings.Count; i++) { ILinearRing innerRing = (ILinearRing) rings[i]; ICoordinate[] innerRingPts = innerRing.Coordinates; for (int j = 0; j < rings.Count; j++) { ILinearRing searchRing = (ILinearRing) rings[j]; ICoordinate[] searchRingPts = searchRing.Coordinates; if (innerRing == searchRing) continue; if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal)) continue; ICoordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph); Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring"); bool isInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts); if (isInside) { nestedPt = innerRingPt; return false; } } } return true; }
public static IEnvelope GetEnvelopeForImage(IMap map, ICoordinate centre, double pixelWidth, double pixelHeight) { var envelope = new Envelope(); ICoordinate size = ImageToWorld(map, pixelWidth, pixelHeight); envelope.SetCentre(centre, size.X, size.Y); return envelope; }
/// <summary> /// /// </summary> /// <param name="pts"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="context"></param> public MonotoneChain(ICoordinate[] pts, int start, int end, object context) { this.pts = pts; this.start = start; this.end = end; this.context = context; }
/// <summary> /// Generates the WKT for a <c>Point</c>. /// </summary> /// <param name="p0">The point coordinate.</param> /// <returns></returns> public static String ToPoint(ICoordinate p0) { if (double.IsNaN(p0.Z)) return "POINT(" + p0.X + " " + p0.Y + ")"; else return "POINT(" + p0.X + " " + p0.Y + " " + p0.Z + ")"; }
/// <summary> /// Generates the WKT for a 2-point <c>LineString</c>. /// </summary> /// <param name="p0">The first coordinate.</param> /// <param name="p1">The second coordinate.</param> /// <returns></returns> public static String ToLineString(ICoordinate p0, ICoordinate p1) { if (double.IsNaN(p0.Z)) return "LINESTRING(" + p0.X + " " + p0.Y + "," + p1.X + " " + p1.Y + ")"; else return "LINESTRING(" + p0.X + " " + p0.Y + " " + p0.Z + "," + p1.X + " " + p1.Y + " " + p1.Z + ")"; }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="ring"></param> /// <returns></returns> public static bool IsPointInRing(ICoordinate p, ICoordinate[] ring) { int i, i1; // point index; i1 = i-1 mod n double xInt; // x intersection of e with ray int crossings = 0; // number of edge/ray crossings double x1,y1,x2,y2; int nPts = ring.Length; /* For each line edge l = (i-1, i), see if it crosses ray from test point in positive x direction. */ for (i = 1; i < nPts; i++ ) { i1 = i - 1; ICoordinate p1 = ring[i]; ICoordinate p2 = ring[i1]; x1 = p1.X - p.X; y1 = p1.Y - p.Y; x2 = p2.X - p.X; y2 = p2.Y - p.Y; if( (( y1 > 0 ) && (y2 <= 0) ) || (( y2 > 0 ) && (y1 <= 0) ) ) { /* e straddles x axis, so compute intersection. */ xInt = (x1 * y2 - x2 * y1) / (y2 - y1); /* crosses ray if strictly positive intersection. */ if (0.0 < xInt) crossings++; } } /* p is inside if an odd number of crossings. */ if ((crossings % 2) == 1) return true; else return false; }
/// <summary> /// Compares two <see cref="Coordinate" />s for their relative position along a segment /// lying in the specified <see cref="Octant" />. /// </summary> /// <param name="octant"></param> /// <param name="p0"></param> /// <param name="p1"></param> /// <returns> /// -1 if node0 occurs first, or /// 0 if the two nodes are equal, or /// 1 if node1 occurs first. /// </returns> public static int Compare(Octants octant, ICoordinate p0, ICoordinate p1) { // nodes can only be equal if their coordinates are equal if (p0.Equals2D(p1)) return 0; int xSign = RelativeSign(p0.X, p1.X); int ySign = RelativeSign(p0.Y, p1.Y); switch (octant) { case Octants.Zero: return CompareValue(xSign, ySign); case Octants.One: return CompareValue(ySign, xSign); case Octants.Two: return CompareValue(ySign, -xSign); case Octants.Three: return CompareValue(-xSign, ySign); case Octants.Four: return CompareValue(-xSign, -ySign); case Octants.Five: return CompareValue(-ySign, -xSign); case Octants.Six: return CompareValue(-ySign, xSign); case Octants.Seven: return CompareValue(xSign, -ySign); } Assert.ShouldNeverReachHere("invalid octant value: " + octant); return 0; }
private int depthDelta = 0; // the change in area depth from the R to Curve side of this edge /// <summary> /// /// </summary> /// <param name="pts"></param> /// <param name="label"></param> public Edge(ICoordinate[] pts, Label label) { eiList = new EdgeIntersectionList(this); this.pts = pts; this.label = label; }
public override void OnMouseDown(ICoordinate worldPosition, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } MapControl.Cursor = Cursors.Hand; Dragging = true; DragImage = (Bitmap)Map.Image.Clone(); StaticToolsImage = new Bitmap(Map.Image.Width, Map.Image.Height); Graphics g = Graphics.FromImage(StaticToolsImage); foreach (IMapTool tool in MapControl.Tools) { if (tool.IsActive) { tool.OnPaint(new PaintEventArgs(g, MapControl.ClientRectangle)); } } g.Dispose(); DragStartPoint = e.Location; DragEndPoint = e.Location; }
private Matrix getAffineTransformMatrix(ICoordinate p01, ICoordinate p02, ICoordinate p03, ICoordinate p11, ICoordinate p12, ICoordinate p13) { Matrix a = new Matrix(new double[,] { { p02.X - p01.X, p02.Y - p01.Y, 0 }, { p03.X - p01.X, p03.Y - p01.Y, 0 }, { p01.X, p01.Y, 1 } }); Matrix b = new Matrix(new double[,] { { p12.X - p11.X, p12.Y - p11.Y, 0 }, { p13.X - p11.X, p13.Y - p11.Y, 0 }, { p11.X, p11.Y, 1 } }); if (!a.IsInvertible) return null; a = a.GetInverseMatrix(); a = a.Multiply(b); a[0, 2] = 0; a[1, 2] = 0; a[2, 2] = 1; return a; }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <param name="pt"></param> /// <returns></returns> public static ICoordinate FindDifferentPoint(ICoordinate[] coord, ICoordinate pt) { foreach (ICoordinate c in coord) if (!c.Equals(pt)) return c; return null; }
public override void OnMouseDown(ICoordinate worldPosition, MouseEventArgs e) { zooming = true; startDragPoint = e.Location; endDragPoint = e.Location; previewImage = (Bitmap)Map.Image.Clone(); }
/// <summary> /// /// </summary> /// <param name="pts1"></param> /// <param name="orientation1"></param> /// <param name="pts2"></param> /// <param name="orientation2"></param> /// <returns></returns> private static int CompareOriented(ICoordinate[] pts1, bool orientation1, ICoordinate[] pts2, bool orientation2) { int dir1 = orientation1 ? 1 : -1; int dir2 = orientation2 ? 1 : -1; int limit1 = orientation1 ? pts1.Length : -1; int limit2 = orientation2 ? pts2.Length : -1; int i1 = orientation1 ? 0 : pts1.Length - 1; int i2 = orientation2 ? 0 : pts2.Length - 1; while (true) { int compPt = pts1[i1].CompareTo(pts2[i2]); if (compPt != 0) return compPt; i1 += dir1; i2 += dir2; bool done1 = i1 == limit1; bool done2 = i2 == limit2; if(done1 && !done2) return -1; if(!done1 && done2) return 1; if(done1 && done2) return 0; } }
/// <summary> /// Tests whether a given point is in an array of points. /// Uses a value-based test. /// </summary> /// <param name="pt">A <c>Coordinate</c> for the test point.</param> /// <param name="pts">An array of <c>Coordinate</c>s to test,</param> /// <returns><c>true</c> if the point is in the array.</returns> public static bool IsInList(ICoordinate pt, ICoordinate[] pts) { foreach (ICoordinate p in pts) if (pt.Equals(p)) return true; return true; }
// 0 0 0 0 // 0 1 0 0 // 0 1 2 0 // 0 1 2 3 0 ... private void AppendCurvePoint(IPolygon polygon, ICoordinate worldPos) { List<ICoordinate> vertices = new List<ICoordinate>(); ILineString linearRing = polygon.ExteriorRing; for (int i = 0; i < linearRing.Coordinates.Length; i++) { if (linearRing.Coordinates.Length <= 4) { if (1 == i) { if (linearRing.Coordinates[0].Equals2D(linearRing.Coordinates[1])) { // 0 0 ? 0 -> 0 1 ? 0 vertices.Add(worldPos); } else { // 0 1 ? 0 -> 0 1 ? 0 vertices.Add(linearRing.Coordinates[i]); } } else if (2 == i) { if (linearRing.Coordinates[1].Equals2D(linearRing.Coordinates[2])) { // 0 0 0 0 -> 0 1 1 0 vertices.Add(worldPos); } else { // 0 1 2 0 -> 0 1 2 3 0 vertices.Add(linearRing.Coordinates[i]); vertices.Add(worldPos); } } else { vertices.Add(linearRing.Coordinates[i]); } } else { if (i == (linearRing.Coordinates.Length - 1)) { // insert before last point to keep ring closed vertices.Add(worldPos); } vertices.Add(linearRing.Coordinates[i]); } } int index = FeatureProvider.GetFeatureCount() - 1; ILinearRing newLinearRing = GeometryFactory.CreateLinearRing(vertices.ToArray()); IPolygon newPolygon = GeometryFactory.CreatePolygon(newLinearRing, null); //##layerEditor.UpdateCurvePointInserted(index, newPolygon, vertices.Count - 1); //((FeatureProvider)layerEditor.VectorLayer.DataSource).UpdateGeometry(index, newPolygon); ((Feature)FeatureProvider.Features[index]).Geometry = newPolygon; Layer.RenderRequired = true; // do not remove see newline MapControl.SelectTool.Select((VectorLayer)Layer, newPolygon, -1); }
/// <summary> /// Adds a point to the current line. /// </summary> /// <param name="pt">The <see cref="Coordinate" /> to add.</param> /// <param name="allowRepeatedPoints">If <c>true</c>, allows the insertions of repeated points.</param> public void Add(ICoordinate pt, bool allowRepeatedPoints) { if (coordList == null) coordList = new CoordinateList(); coordList.Add(pt, allowRepeatedPoints); lastPt = pt; }
/// <summary> /// Finds a point in a list of points which is not contained in another list of points. /// </summary> /// <param name="testPts">The <c>Coordinate</c>s to test.</param> /// <param name="pts">An array of <c>Coordinate</c>s to test the input points against.</param> /// <returns>A <c>Coordinate</c> from <c>testPts</c> which is not in <c>pts</c>, /// or <c>null</c>.</returns> public static ICoordinate PointNotInList(ICoordinate[] testPts, ICoordinate[] pts) { foreach (ICoordinate testPt in testPts) if (!IsInList(testPt, pts)) return testPt; return null; }
public void Start(INode node, AddRelatedFeature addRelatedFeature, int level) { lastFeature = node; lastRelatedFeatureGeometries.Clear(); lastRelatedFeatures = new List<IFeature>(); lastRelatedNewFeatures = new List<IFeature>(); lastCoordinate = (ICoordinate)node.Geometry.Coordinates[0].Clone(); foreach (IBranch branch in node.IncomingBranches) { lastRelatedFeatures.Add(branch); var clone = (IBranch)branch.Clone(); lastRelatedNewFeatures.Add(clone); lastRelatedFeatureGeometries.Add((IGeometry)clone.Geometry.Clone()); if (null != addRelatedFeature) { activeInRules.Add(new List<IFeatureRelationInteractor>()); addRelatedFeature(activeInRules[activeInRules.Count - 1], branch, clone, level); } } foreach (var branch in node.OutgoingBranches) { lastRelatedFeatures.Add(branch); var clone = (IBranch) branch.Clone(); lastRelatedNewFeatures.Add(clone); lastRelatedFeatureGeometries.Add((IGeometry)clone.Geometry.Clone()); if (null != addRelatedFeature) { activeOutRules.Add(new List<IFeatureRelationInteractor>()); addRelatedFeature(activeOutRules[activeOutRules.Count - 1], branch, clone, level); } } }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="geom"></param> private void ComputeLocation(ICoordinate p, IGeometry geom) { if (geom is ILineString) UpdateLocationInfo(Locate(p, (ILineString) geom)); else if(geom is Polygon) UpdateLocationInfo(Locate(p, (IPolygon) geom)); else if(geom is IMultiLineString) { IMultiLineString ml = (IMultiLineString) geom; foreach (ILineString l in ml.Geometries) UpdateLocationInfo(Locate(p, l)); } else if(geom is IMultiPolygon) { IMultiPolygon mpoly = (IMultiPolygon) geom; foreach (IPolygon poly in mpoly.Geometries) UpdateLocationInfo(Locate(p, poly)); } else if (geom is IGeometryCollection) { IEnumerator geomi = new GeometryCollectionEnumerator((IGeometryCollection) geom); while(geomi.MoveNext()) { IGeometry g2 = (IGeometry) geomi.Current; if (g2 != geom) ComputeLocation(p, g2); } } }
/// <summary> /// /// </summary> /// <param name="coordinate"></param> /// <param name="writer"></param> protected void Write(ICoordinate coordinate, XmlTextWriter writer) { writer.WriteStartElement(GMLElements.gmlPrefix, "coord", GMLElements.gmlNS); writer.WriteElementString(GMLElements.gmlPrefix, "X", GMLElements.gmlNS, coordinate.X.ToString("g", NumberFormatter)); writer.WriteElementString(GMLElements.gmlPrefix, "Y", GMLElements.gmlNS, coordinate.Y.ToString("g", NumberFormatter)); writer.WriteEndElement(); }
///// <summary> ///// snapping specific for a tool. Called before layer specific snappping is applied. ///// </summary> ///// <param name="sourceLayer"></param> ///// <param name="snapSource"></param> ///// <param name="worldPos"></param> ///// <param name="Envelope"></param> ///// <returns></returns> public void Snap(ILayer sourceLayer, IGeometry snapSource, ICoordinate worldPos, IEnvelope Envelope) { SnapResult = null; IFeature sourceFeature = MapControl.SelectTool.FeatureEditors[0].SourceFeature; if (sourceFeature.Geometry != snapSource) return; SnapRole snapRole = SnapRole.FreeAtObject; if ((Control.ModifierKeys & Keys.Control) == Keys.Control) snapRole = SnapRole.Free; ISnapRule snapRule = new SnapRule { SourceLayer = sourceLayer, TargetLayer = sourceLayer, Obligatory = true, SnapRole = snapRole, PixelGravity = 4 }; SnapResult = MapControl.SnapTool.ExecuteSnapRule( snapRule, sourceFeature, sourceFeature.Geometry, new List<IFeature> { sourceFeature }, worldPos, -1); }
private void AddCoordinates(ICoordinate[] coordinates) { int points = 0; Array.ForEach<ICoordinate>(coordinates, delegate(ICoordinate coordinate) { double? z = null; if (!double.IsNaN(coordinate.Z) && !double.IsInfinity(coordinate.Z)) { z = coordinate.Z; } if (points == 0) { builder.BeginFigure(coordinate.X, coordinate.Y, z, null); } else { builder.AddLine(coordinate.X, coordinate.Y, z, null); } points++; }); if (points != 0) { builder.EndFigure(); } }
/// <summary> /// snapping specific for a tool. Called before layer specific snapping is applied. /// </summary> /// <returns></returns> private void Snap(IGeometry snapSource, ICoordinate worldPos) { SnapResult = null; var sourceFeature = SelectTool.SelectedFeatureInteractors[0].SourceFeature; if (!Equals(sourceFeature.Geometry, snapSource)) { return; } SnapRole snapRole; if (Mode == EditMode.Add) { snapRole = SnapRole.FreeAtObject; if ((Control.ModifierKeys & Keys.Control) == Keys.Control) snapRole = SnapRole.Free; } else { snapRole = SnapRole.AllTrackers; } ISnapRule snapRule = new SnapRule {Obligatory = true, SnapRole = snapRole, PixelGravity = 4}; SnapResult = MapControl.SnapTool.ExecuteSnapRule(snapRule, sourceFeature, sourceFeature.Geometry, new List<IFeature> {sourceFeature}, worldPos, -1); }
/// <summary> /// Creates a new segment string from a list of vertices. /// </summary> /// <param name="pts">The vertices of the segment string.</param> /// <param name="data">The user-defined data of this segment string (may be null).</param> public SegmentString(ICoordinate[] pts, Object data) { nodeList = new SegmentNodeList(this); this.pts = pts; Data = data; }
public override void OnMouseDown(ICoordinate worldPosition, MouseEventArgs e) { if (VectorLayer == null) { return; } if (e.Button != MouseButtons.Left) { return; } isBusy = true; StartDrawing(); newNetworkFeature = GeometryFactory.CreatePoint(worldPosition); ((DataTableFeatureProvider)newNetworkFeatureLayer.DataSource).Clear(); newNetworkFeatureLayer.DataSource.Add(newNetworkFeature); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(VectorLayer, null, newNetworkFeature, worldPosition, -1); //TODO check: why is this commented out in trunk? if (snapResult != null) { newNetworkFeature.Coordinates[0].X = snapResult.Location.X; newNetworkFeature.Coordinates[0].Y = snapResult.Location.Y; } newNetworkFeatureLayer.Style = MapControl.SnapTool.Failed ? errorNetworkFeatureStyle : networkFeatureStyle; }
/// <summary> /// Test the point q to see whether it intersects the Envelope /// defined by p1-p2. /// </summary> /// <param name="p1">One extremal point of the envelope.</param> /// <param name="p2">Another extremal point of the envelope.</param> /// <param name="q">Point to test for intersection.</param> /// <returns><c>true</c> if q intersects the envelope p1-p2.</returns> public static bool Intersects(ICoordinate p1, ICoordinate p2, ICoordinate q) { if (((q.X >= (p1.X < p2.X ? p1.X : p2.X)) && (q.X <= (p1.X > p2.X ? p1.X : p2.X))) && ((q.Y >= (p1.Y < p2.Y ? p1.Y : p2.Y)) && (q.Y <= (p1.Y > p2.Y ? p1.Y : p2.Y)))) return true; return false; }
public static ExtendedCoordinate[] Copy(ICoordinate[] coordinates) { ExtendedCoordinate[] copy = new ExtendedCoordinate[coordinates.Length]; for (int i = 0; i < coordinates.Length; i++) copy[i] = new ExtendedCoordinate(coordinates[i]); return copy; }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="seg"></param> private void TestLineSegment(ICoordinate p, LineSegment seg) { double xInt; // x intersection of segment with ray double x1; // translated coordinates double y1; double x2; double y2; /* * Test if segment crosses ray from test point in positive x direction. */ ICoordinate p1 = seg.P0; ICoordinate p2 = seg.P1; x1 = p1.X - p.X; y1 = p1.Y - p.Y; x2 = p2.X - p.X; y2 = p2.Y - p.Y; if (((y1 > 0) && (y2 <= 0)) || ((y2 > 0) && (y1 <= 0))) { /* * segment straddles x axis, so compute intersection. */ xInt = RobustDeterminant.SignOfDet2x2(x1, y1, x2, y2) / (y2 - y1); /* * crosses ray if strictly positive intersection. */ if (0.0 < xInt) crossings++; } }
/// <summary> /// Initialize an <c>Envelope</c> for a region defined by a single Coordinate. /// </summary> /// <param name="p">The Coordinate.</param> void IEnvelope.Init(ICoordinate p) { Init(p.X, p.X, p.Y, p.Y); }
/// <summary> /// Moves the envelope to the indicated coordinate. /// </summary> /// <param name="centre">The new centre coordinate.</param> void IEnvelope.SetCentre(ICoordinate centre) { ((IEnvelope)this).SetCentre(centre, Width, Height); }
///<summary> /// Tests if the given point lies in or on the envelope. ///</summary> /// <param name="p">the point which this <c>Envelope</c> is being checked for containing</param> /// <returns><c>true</c> if the point lies in the interior or on the boundary of this <c>Envelope</c>.</returns> bool IEnvelope.Covers(ICoordinate p) { return(Covers(p.X, p.Y)); }
///<summary> /// Tests if the given point lies in or on the envelope. ///</summary> /// <remarks> /// Note that this is <b>not</b> the same definition as the SFS <i>contains</i>, /// which would exclude the envelope boundary. /// </remarks> /// <param name="p">the point which this <c>Envelope</c> is being checked for containing</param> /// <returns><c>true</c> if the point lies in the interior or on the boundary of this <c>Envelope</c>. </returns> /// <see cref="IEnvelope.Covers(ICoordinate)"/> bool IEnvelope.Contains(ICoordinate p) { return(((IEnvelope)this).Covers(p)); }
/// <summary> /// Check if the point <c>p</c> overlaps (lies inside) the region of this <c>Envelope</c>. /// </summary> /// <param name="p"> the <c>Coordinate</c> to be tested.</param> /// <returns><c>true</c> if the point overlaps this <c>Envelope</c>.</returns> bool IEnvelope.Intersects(ICoordinate p) { return(Intersects(p.X, p.Y)); }
bool IEnvelope.Overlaps(ICoordinate p) { return(((IEnvelope)this).Intersects(p)); }
/// <summary> /// Enlarges this <code>Envelope</code> so that it contains /// the given <see cref="ICoordinate"/>. /// Has no effect if the point is already on or within the envelope. /// </summary> /// <param name="p">The Coordinate.</param> void IEnvelope.ExpandToInclude(ICoordinate p) { ExpandToInclude(p.X, p.Y); }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="q1"></param> /// <param name="q2"></param> /// <returns></returns> public override int ComputeIntersect(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2) { isProper = false; // first try a fast test to see if the envelopes of the lines intersect if (!Envelope.Intersects(p1, p2, q1, q2)) { return(DontIntersect); } // for each endpoint, compute which side of the other segment it lies // if both endpoints lie on the same side of the other segment, // the segments do not intersect int Pq1 = CGAlgorithms.OrientationIndex(p1, p2, q1); int Pq2 = CGAlgorithms.OrientationIndex(p1, p2, q2); if ((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { return(DontIntersect); } int Qp1 = CGAlgorithms.OrientationIndex(q1, q2, p1); int Qp2 = CGAlgorithms.OrientationIndex(q1, q2, p2); if ((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { return(DontIntersect); } bool collinear = (Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0); if (collinear) { return(ComputeCollinearIntersection(p1, p2, q1, q2)); } /* * Check if the intersection is an endpoint. If it is, copy the endpoint as * the intersection point. Copying the point rather than computing it * ensures the point has the exact value, which is important for * robustness. It is sufficient to simply check for an endpoint which is on * the other line, since at this point we know that the inputLines must * intersect. */ if (Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { isProper = false; if (Pq1 == 0) { intPt[0] = new Coordinate(q1); } if (Pq2 == 0) { intPt[0] = new Coordinate(q2); } if (Qp1 == 0) { intPt[0] = new Coordinate(p1); } if (Qp2 == 0) { intPt[0] = new Coordinate(p2); } } else { isProper = true; intPt[0] = Intersection(p1, p2, q1, q2); } return(DoIntersect); }
/// <summary> /// /// </summary> /// <param name="n1"></param> /// <param name="n2"></param> /// <param name="n3"></param> /// <param name="n4"></param> /// <param name="normPt"></param> private void NormalizeToMinimum(ICoordinate n1, ICoordinate n2, ICoordinate n3, ICoordinate n4, ICoordinate normPt) { normPt.X = SmallestInAbsValue(n1.X, n2.X, n3.X, n4.X); normPt.Y = SmallestInAbsValue(n1.Y, n2.Y, n3.Y, n4.Y); n1.X -= normPt.X; n1.Y -= normPt.Y; n2.X -= normPt.X; n2.Y -= normPt.Y; n3.X -= normPt.X; n3.Y -= normPt.Y; n4.X -= normPt.X; n4.Y -= normPt.Y; }
/// <summary> /// Initialize an <c>Envelope</c> for a region defined by two Coordinates. /// </summary> /// <param name="p1">The first Coordinate.</param> /// <param name="p2">The second Coordinate.</param> void IEnvelope.Init(ICoordinate p1, ICoordinate p2) { Init(p1.X, p2.X, p1.Y, p2.Y); }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="q1"></param> /// <param name="q2"></param> /// <returns></returns> private int ComputeCollinearIntersection(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2) { bool p1q1p2 = Envelope.Intersects(p1, p2, q1); bool p1q2p2 = Envelope.Intersects(p1, p2, q2); bool q1p1q2 = Envelope.Intersects(q1, q2, p1); bool q1p2q2 = Envelope.Intersects(q1, q2, p2); if (p1q1p2 && p1q2p2) { intPt[0] = q1; intPt[1] = q2; return(Collinear); } if (q1p1q2 && q1p2q2) { intPt[0] = p1; intPt[1] = p2; return(Collinear); } if (p1q1p2 && q1p1q2) { intPt[0] = q1; intPt[1] = p1; return(q1.Equals(p1) && !p1q2p2 && !q1p2q2 ? DoIntersect : Collinear); } if (p1q1p2 && q1p2q2) { intPt[0] = q1; intPt[1] = p2; return(q1.Equals(p2) && !p1q2p2 && !q1p1q2 ? DoIntersect : Collinear); } if (p1q2p2 && q1p1q2) { intPt[0] = q2; intPt[1] = p1; return(q2.Equals(p1) && !p1q1p2 && !q1p2q2 ? DoIntersect : Collinear); } if (p1q2p2 && q1p2q2) { intPt[0] = q2; intPt[1] = p2; return(q2.Equals(p2) && !p1q1p2 && !q1p1q2 ? DoIntersect : Collinear); } return(DontIntersect); }
/// <summary> /// Normalize the supplied coordinates to /// so that the midpoint of their intersection envelope /// lies at the origin. /// </summary> /// <param name="n00"></param> /// <param name="n01"></param> /// <param name="n10"></param> /// <param name="n11"></param> /// <param name="normPt"></param> private void NormalizeToEnvCentre(ICoordinate n00, ICoordinate n01, ICoordinate n10, ICoordinate n11, ICoordinate normPt) { double minX0 = n00.X < n01.X ? n00.X : n01.X; double minY0 = n00.Y < n01.Y ? n00.Y : n01.Y; double maxX0 = n00.X > n01.X ? n00.X : n01.X; double maxY0 = n00.Y > n01.Y ? n00.Y : n01.Y; double minX1 = n10.X < n11.X ? n10.X : n11.X; double minY1 = n10.Y < n11.Y ? n10.Y : n11.Y; double maxX1 = n10.X > n11.X ? n10.X : n11.X; double maxY1 = n10.Y > n11.Y ? n10.Y : n11.Y; double intMinX = minX0 > minX1 ? minX0 : minX1; double intMaxX = maxX0 < maxX1 ? maxX0 : maxX1; double intMinY = minY0 > minY1 ? minY0 : minY1; double intMaxY = maxY0 < maxY1 ? maxY0 : maxY1; double intMidX = (intMinX + intMaxX) / 2.0; double intMidY = (intMinY + intMaxY) / 2.0; normPt.X = intMidX; normPt.Y = intMidY; n00.X -= normPt.X; n00.Y -= normPt.Y; n01.X -= normPt.X; n01.Y -= normPt.Y; n10.X -= normPt.X; n10.Y -= normPt.Y; n11.X -= normPt.X; n11.Y -= normPt.Y; }
public static double Distance(this ICoordinate x, double lat, double lon) { return(GCDis.Distance(x.Lat, x.Lon, lat, lon)); }
/// <summary> /// This method computes the actual value of the intersection point. /// To obtain the maximum precision from the intersection calculation, /// the coordinates are normalized by subtracting the minimum /// ordinate values (in absolute value). This has the effect of /// removing common significant digits from the calculation to /// maintain more bits of precision. /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="q1"></param> /// <param name="q2"></param> /// <returns></returns> private ICoordinate Intersection(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2) { ICoordinate n1 = new Coordinate(p1); ICoordinate n2 = new Coordinate(p2); ICoordinate n3 = new Coordinate(q1); ICoordinate n4 = new Coordinate(q2); ICoordinate normPt = new Coordinate(); NormalizeToEnvCentre(n1, n2, n3, n4, normPt); ICoordinate intPt = null; try { intPt = HCoordinate.Intersection(n1, n2, n3, n4); } catch (NotRepresentableException) { Assert.ShouldNeverReachHere("Coordinate for intersection is not calculable"); } intPt.X += normPt.X; intPt.Y += normPt.Y; /* * * MD - May 4 2005 - This is still a problem. Here is a failure case: * * LINESTRING (2089426.5233462777 1180182.3877339689, 2085646.6891757075 1195618.7333999649) * LINESTRING (1889281.8148903656 1997547.0560044837, 2259977.3672235999 483675.17050843034) * int point = (2097408.2633752143,1144595.8008114607) */ if (!IsInSegmentEnvelopes(intPt)) { Trace.WriteLine("Intersection outside segment envelopes: " + intPt); } /* * // disabled until a better solution is found * if(!IsInSegmentEnvelopes(intPt)) * { * Trace.WriteLine("first value outside segment envelopes: " + intPt); * * IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2); * intPt = ibi.Intersection; * } * if(!IsInSegmentEnvelopes(intPt)) * { * Trace.WriteLine("ERROR - outside segment envelopes: " + intPt); * * IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2); * Coordinate testPt = ibi.Intersection; * } */ if (precisionModel != null) { precisionModel.MakePrecise(intPt); } return(intPt); }
public static bool LatLonEquals(this ICoordinate x, ICoordinate y, double delta = 0.0) { return(Abs(x.Lat - y.Lat) <= delta && Abs(x.Lon - y.Lon) <= delta); }
/// <exception cref="InvalidOperationException"></exception> /// <exception cref="ArgumentNullException"></exception> public static T GetClosest <T>(this IEnumerable <T> items, ICoordinate coordinate) where T : ICoordinate { return(items.GetClosest(coordinate.Lat, coordinate.Lon)); }
/// <summary> /// Constructs a Node with the given location and collection of outgoing DirectedEdges. /// </summary> /// <param name="pt"></param> /// <param name="deStar"></param> public Node(ICoordinate pt, DirectedEdgeStar deStar) { this.pt = pt; this.deStar = deStar; }
public static double Distance(this ICoordinate x, ICoordinate y) { return(Distance(x, y.Lat, y.Lon)); }
/// <summary> /// Removes this node from its containing graph. /// </summary> internal void Remove() { pt = null; }
private static Polygon getSegmentPreBuffer(Segment segment, double distance, int pointsPerCircle, bool bothSides) { if (distance < 0) { return(new Polygon()); } ICoordinate[] points1 = null; ICoordinate[] points2 = null; if (segment.V1.X == segment.V2.X) { bool downToUp = segment.V1.Y < segment.V2.Y; points1 = getArcPoints(downToUp ? segment.V1 : segment.V2, Math.PI, 2 * Math.PI, distance, downToUp && !bothSides ? 2 : pointsPerCircle); points2 = getArcPoints(downToUp ? segment.V2 : segment.V1, 0, Math.PI, distance, !downToUp && !bothSides ? 2 : pointsPerCircle); Polygon result = new Polygon(points1); foreach (ICoordinate p in points2) { result.Contours[0].Vertices.Add(p); } return(result); } if (segment.V1.Y == segment.V2.Y) { bool leftToRight = segment.V1.X < segment.V2.X; points1 = getArcPoints(leftToRight ? segment.V1 : segment.V2, 0.5 * Math.PI, 1.5 * Math.PI, distance, leftToRight && !bothSides ? 2 : pointsPerCircle); points2 = getArcPoints(leftToRight ? segment.V2 : segment.V1, 1.5 * Math.PI, 2.5 * Math.PI, distance, !leftToRight && !bothSides ? 2 : pointsPerCircle); Polygon result = new Polygon(points1); foreach (ICoordinate p in points2) { result.Contours[0].Vertices.Add(p); } return(result); } double angle = Math.Atan(Math.Abs(segment.V2.Y - segment.V1.Y) / Math.Abs(segment.V2.X - segment.V1.X)); bool wasSwapped = false; if (segment.V1.X > segment.V2.X) { ICoordinate p = segment.V1; segment.V1 = segment.V2; segment.V2 = p; wasSwapped = true; } if (segment.V1.Y < segment.V2.Y) { points1 = getArcPoints(segment.V1, angle + 0.5 * Math.PI, angle + 1.5 * Math.PI, distance, !bothSides && !wasSwapped ? 2 : pointsPerCircle); points2 = getArcPoints(segment.V2, angle - 0.5 * Math.PI, angle + 0.5 * Math.PI, distance, !bothSides && wasSwapped ? 2 : pointsPerCircle); Polygon result = new Polygon(points1); foreach (ICoordinate p in points2) { result.Contours[0].Vertices.Add(p); } return(result); } else { points1 = getArcPoints(segment.V1, 0.5 * Math.PI - angle, 1.5 * Math.PI - angle, distance, !bothSides && !wasSwapped ? 2 : pointsPerCircle); points2 = getArcPoints(segment.V2, 1.5 * Math.PI - angle, 2.5 * Math.PI - angle, distance, !bothSides && wasSwapped ? 2 : pointsPerCircle); Polygon result = new Polygon(points1); foreach (ICoordinate p in points2) { result.Contours[0].Vertices.Add(p); } return(result); } }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <param name="edges"></param> public Node(ICoordinate coord, EdgeEndStar edges) { this.coord = coord; this.edges = edges; label = new Label(0, Locations.Null); }
/// <summary> /// Constructs a Node with the given location. /// </summary> /// <param name="pt"></param> public Node(ICoordinate pt) : this(pt, new DirectedEdgeStar()) { }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> /// <param name="p4"></param> /// <returns></returns> private int ComputeCollinearIntersection(ICoordinate p1, ICoordinate p2, ICoordinate p3, ICoordinate p4) { double r1; double r2; double r3; double r4; ICoordinate q3; ICoordinate q4; double t3; double t4; r1 = 0; r2 = 1; r3 = RParameter(p1, p2, p3); r4 = RParameter(p1, p2, p4); // make sure p3-p4 is in same direction as p1-p2 if (r3 < r4) { q3 = p3; t3 = r3; q4 = p4; t4 = r4; } else { q3 = p4; t3 = r4; q4 = p3; t4 = r3; } // check for no intersection if (t3 > r2 || t4 < r1) { return(DontIntersect); } // check for single point intersection if (q4 == p1) { pa.CoordinateValue = p1; return(DoIntersect); } if (q3 == p2) { pa.CoordinateValue = p2; return(DoIntersect); } // intersection MUST be a segment - compute endpoints pa.CoordinateValue = p1; if (t3 > r1) { pa.CoordinateValue = q3; } pb.CoordinateValue = p2; if (t4 < r2) { pb.CoordinateValue = q4; } return(Collinear); }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <returns></returns> public override Node CreateNode(ICoordinate coord) { return(new Node(coord, new DirectedEdgeStar())); }
public static Tuple <List <ICoordinate>, List <bool> > RandomizeCoordinatesAndSave(int numcoords, ConfigParams Config, bool save = true) { List <ICoordinate> coordinates = new List <ICoordinate>(); List <bool> labels = new List <bool>(); bool instance_created = false; while (!instance_created) { if ((Config.ActionList & Actions.Instance_Uniform) != 0) { for (var i = 0; i < numcoords; i++) { if (StaticConfigParams.RandomInstanceType == typeof(Coordinate)) { coordinates.Add(Coordinate.MakeRandom()); } else if (StaticConfigParams.RandomInstanceType == typeof(Coordinate3D)) { coordinates.Add(Coordinate3D.MakeRandom()); } labels.Add(StaticConfigParams.rnd.NextDouble() > StaticConfigParams.CONST_NEGATIVELABELRATE); } } if ((Config.ActionList & Actions.Instance_PlantedSingleEnrichment) != 0) { for (var i = 0; i < numcoords; i++) { if (StaticConfigParams.RandomInstanceType == typeof(Coordinate)) { coordinates.Add(Coordinate.MakeRandom()); } else if (StaticConfigParams.RandomInstanceType == typeof(Coordinate3D)) { coordinates.Add(Coordinate3D.MakeRandom()); } } ICoordinate pivotCoord = null; if (StaticConfigParams.RandomInstanceType == typeof(Coordinate)) { pivotCoord = Coordinate.MakeRandom(); } else if (StaticConfigParams.RandomInstanceType == typeof(Coordinate3D)) { pivotCoord = Coordinate3D.MakeRandom(); } var prPos = (int)Math.Round((1.0 - StaticConfigParams.CONST_NEGATIVELABELRATE) * numcoords); mHGJumper.Initialize(prPos, numcoords - prPos); coordinates = coordinates.OrderBy(t => t.EuclideanDistance(pivotCoord)).ToList(); labels = mHGJumper.SampleSignificantEnrichmentVector(1e-3).ToList(); Console.WriteLine($"Instantiated sample with p={mHGJumper.minimumHypergeometric(labels.ToArray()).Item1:e} around pivot {pivotCoord.ToString()}"); mHGJumper.optHGT = 0.05; } instance_created = labels.Any(); } if (save) { Generics.SaveToCSV(coordinates.Zip(labels, (a, b) => a.ToString() + "," + Convert.ToDouble(b)), $@"coords_{StaticConfigParams.filenamesuffix}.csv"); } return(new Tuple <List <ICoordinate>, List <bool> >(coordinates, labels)); }
public void GenerateEmpricialDensityGrid(long numsamples, List <Tuple <ICoordinate, bool> > lableddata, double jitterscale = 1E-7) { producer = Task.Run(() => { var pairs = new List <Tuple <ICoordinate, ICoordinate> >(); for (var i = 0; i < lableddata.Count - 1; i++) { for (var j = i + 1; j < lableddata.Count; j++) { if (lableddata[i].Item2 != lableddata[j].Item2) { pairs.Add(new Tuple <ICoordinate, ICoordinate>(lableddata[i].Item1, lableddata[j].Item1)); } } } //add bottom boundary var problemDim = lableddata.First().Item1.GetDimensionality(); switch (problemDim) { case 2: pairs.Add(new Tuple <ICoordinate, ICoordinate>(new Coordinate(0, 0), new Coordinate(jitterscale, -20))); break; case 3: pairs.Add(new Tuple <ICoordinate, ICoordinate>(new Coordinate3D(0, 0, 0), new Coordinate3D(jitterscale, jitterscale, -20))); break; } Parallel.For(0, numsamples, (i) => { var inducers = pairs.OrderBy(v => StaticConfigParams.rnd.NextDouble()).Take(problemDim).ToList(); ICoordinate intersectionCoord, first_coord, second_coord, third_coord, jitteredPivot = null; switch (problemDim) { case 2: var firstbisectorLine = Line.Bisector((Coordinate)inducers[0].Item1, (Coordinate)inducers[0].Item2, isCounted: false); var secondbisectorLine = Line.Bisector((Coordinate)inducers[1].Item1, (Coordinate)inducers[1].Item2, isCounted: false); intersectionCoord = firstbisectorLine.Intersection(secondbisectorLine); //empirical gradient var first_posdir = firstbisectorLine.EvaluateAtX(intersectionCoord.GetDimension(0) + jitterscale); var first_negdir = firstbisectorLine.EvaluateAtX(intersectionCoord.GetDimension(0) - jitterscale); var second_posdir = secondbisectorLine.EvaluateAtX(intersectionCoord.GetDimension(0) + jitterscale); var second_negdir = secondbisectorLine.EvaluateAtX(intersectionCoord.GetDimension(0) - jitterscale); //Find local minima directions. first_coord = first_posdir > first_negdir ? new Coordinate(intersectionCoord.GetDimension(0) + jitterscale, first_posdir) : new Coordinate(intersectionCoord.GetDimension(0) - jitterscale, first_negdir); second_coord = second_posdir > second_negdir ? new Coordinate(intersectionCoord.GetDimension(0) + jitterscale, second_posdir) : new Coordinate(intersectionCoord.GetDimension(0) - jitterscale, second_negdir); //averaging ensures we are in the exact cell who's bottom-most coordinate is the intersection coord. jitteredPivot = new Coordinate(first_coord.GetDimension(0) + second_coord.GetDimension(0) / 2.0, first_coord.GetDimension(1) + second_coord.GetDimension(1) / 2.0); /* * // Note: I abandoned the Random sampled jitter strategy since this simpler strategy ensures a 1-1 mapping between an intersectionCoord and a cell (up to scale). * var jitteredPivot = new Coordinate( * intersectionCoord.X + GeometryHelpers.SampleGaussian(StaticConfigParams.rnd, 0.0, jitterscale), * intersectionCoord.Y + GeometryHelpers.SampleGaussian(StaticConfigParams.rnd, 0.0, jitterscale)); */ break; case 3: var firstbisectorPlane = Plane.Bisector((Coordinate3D)inducers[0].Item1, (Coordinate3D)inducers[0].Item2); var secondbisectorPlane = Plane.Bisector((Coordinate3D)inducers[1].Item1, (Coordinate3D)inducers[1].Item2); var thirdbisectorPlane = Plane.Bisector((Coordinate3D)inducers[2].Item1, (Coordinate3D)inducers[2].Item2); //We find the intersection of three planes by solving a system of linear equations. double[,] matrix = { { firstbisectorPlane.Normal.X, firstbisectorPlane.Normal.Y, firstbisectorPlane.Normal.Z }, { secondbisectorPlane.Normal.X, secondbisectorPlane.Normal.Y, secondbisectorPlane.Normal.Z }, { thirdbisectorPlane.Normal.X, thirdbisectorPlane.Normal.Y, thirdbisectorPlane.Normal.Z } }; double[,] rightSide = { { -firstbisectorPlane.D }, { -secondbisectorPlane.D }, { -thirdbisectorPlane.D } }; var x = Matrix.Solve(matrix, rightSide, leastSquares: true); intersectionCoord = new Coordinate3D(x[0, 0], x[1, 0], x[2, 0]); //empirical gradients dy first_coord = (Coordinate3D)intersectionCoord + firstbisectorPlane.Normal.Scale(jitterscale); second_coord = (Coordinate3D)intersectionCoord + secondbisectorPlane.Normal.Scale(jitterscale); third_coord = (Coordinate3D)intersectionCoord + thirdbisectorPlane.Normal.Scale(jitterscale); jitteredPivot = new Coordinate3D((first_coord.GetDimension(0) + second_coord.GetDimension(0) + third_coord.GetDimension(0)) / 3.0, (first_coord.GetDimension(1) + second_coord.GetDimension(1) + third_coord.GetDimension(1)) / 3.0, (first_coord.GetDimension(2) + second_coord.GetDimension(2) + third_coord.GetDimension(2)) / 3.0); break; } pivots.Add(jitteredPivot); }); pivots.CompleteAdding(); }); }
public override void OnMouseDown(ICoordinate worldPosition, System.Windows.Forms.MouseEventArgs e) { //do not allow user to select this tool. // base.OnMouseDown(worldPosition, e); }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> /// <param name="p4"></param> /// <returns></returns> public override int ComputeIntersect(ICoordinate p1, ICoordinate p2, ICoordinate p3, ICoordinate p4) { double a1; double b1; double c1; double a2; double b2; double c2; /* * Coefficients of line eqns. */ double r1; double r2; double r3; double r4; /* * 'Sign' values */ isProper = false; /* * Compute a1, b1, c1, where line joining points 1 and 2 * is "a1 x + b1 y + c1 = 0". */ a1 = p2.Y - p1.Y; b1 = p1.X - p2.X; c1 = p2.X * p1.Y - p1.X * p2.Y; /* * Compute r3 and r4. */ r3 = a1 * p3.X + b1 * p3.Y + c1; r4 = a1 * p4.X + b1 * p4.Y + c1; /* * Check signs of r3 and r4. If both point 3 and point 4 lie on * same side of line 1, the line segments do not intersect. */ if (r3 != 0 && r4 != 0 && IsSameSignAndNonZero(r3, r4)) { return(DontIntersect); } /* * Compute a2, b2, c2 */ a2 = p4.Y - p3.Y; b2 = p3.X - p4.X; c2 = p4.X * p3.Y - p3.X * p4.Y; /* * Compute r1 and r2 */ r1 = a2 * p1.X + b2 * p1.Y + c2; r2 = a2 * p2.X + b2 * p2.Y + c2; /* * Check signs of r1 and r2. If both point 1 and point 2 lie * on same side of second line segment, the line segments do * not intersect. */ if (r1 != 0 && r2 != 0 && IsSameSignAndNonZero(r1, r2)) { return(DontIntersect); } /* * Line segments intersect: compute intersection point. */ double denom = a1 * b2 - a2 * b1; if (denom == 0) { return(ComputeCollinearIntersection(p1, p2, p3, p4)); } double numX = b1 * c2 - b2 * c1; pa.X = numX / denom; double numY = a2 * c1 - a1 * c2; pa.Y = numY / denom; // check if this is a proper intersection BEFORE truncating values, // to avoid spurious equality comparisons with endpoints isProper = true; if (pa.Equals(p1) || pa.Equals(p2) || pa.Equals(p3) || pa.Equals(p4)) { isProper = false; } // truncate computed point to precision grid if (precisionModel != null) { precisionModel.MakePrecise(pa); } return(DoIntersect); }
/// <summary> /// /// </summary> /// <param name="coord"></param> public void Filter(ICoordinate coord) { commonBitsX.Add(coord.X); commonBitsY.Add(coord.Y); }
/// <summary> /// Constructs a LineMergeDirectedEdge connecting the <c>from</c> node to the <c>to</c> node. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="directionPt"> /// specifies this DirectedEdge's direction (given by an imaginary /// line from the <c>from</c> node to <c>directionPt</c>). /// </param> /// <param name="edgeDirection"> /// whether this DirectedEdge's direction is the same as or /// opposite to that of the parent Edge (if any). /// </param> public LineMergeDirectedEdge(Node from, Node to, ICoordinate directionPt, bool edgeDirection) : base(from, to, directionPt, edgeDirection) { }