示例#1
0
 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();
 }
示例#2
0
        /// <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;
        }
示例#4
0
 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;
 }
示例#5
0
 /// <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;
 }
示例#6
0
        /// <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 + ")";
		}
示例#7
0
        /// <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;
        }
示例#10
0
文件: Edge.cs 项目: lishxi/_SharpMap
        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;
        }
示例#11
0
        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;
        }
示例#12
0
        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;
 }
示例#14
0
 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;
            }
        }
示例#16
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;
 }
示例#17
0
        // 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);
        }
示例#18
0
 /// <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;
 }
示例#19
0
 /// <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);
                }
            }
        }
示例#21
0
 /// <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);
         }
     }
 }
示例#22
0
 /// <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();
 }
示例#23
0
        ///// <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();
     }
 }
示例#25
0
        /// <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);
        }
示例#26
0
        /// <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;
        }
示例#27
0
        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;
        }
示例#28
0
 /// <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++;            
            }
        }
示例#31
0
 /// <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);
 }
示例#32
0
 /// <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);
 }
示例#33
0
 ///<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));
 }
示例#34
0
 ///<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));
 }
示例#35
0
 /// <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));
 }
示例#36
0
 bool IEnvelope.Overlaps(ICoordinate p)
 {
     return(((IEnvelope)this).Intersects(p));
 }
示例#37
0
 /// <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);
 }
示例#38
0
        /// <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);
        }
示例#39
0
 /// <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;
 }
示例#40
0
 /// <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);
 }
示例#41
0
        /// <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);
        }
示例#42
0
        /// <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;
        }
示例#43
0
 public static double Distance(this ICoordinate x, double lat, double lon)
 {
     return(GCDis.Distance(x.Lat, x.Lon, lat, lon));
 }
示例#44
0
        /// <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);
        }
示例#45
0
 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);
 }
示例#46
0
 /// <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));
 }
示例#47
0
 /// <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;
 }
示例#48
0
 public static double Distance(this ICoordinate x, ICoordinate y)
 {
     return(Distance(x, y.Lat, y.Lon));
 }
示例#49
0
 /// <summary>
 /// Removes this node from its containing graph.
 /// </summary>
 internal void Remove()
 {
     pt = null;
 }
示例#50
0
        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);
            }
        }
示例#51
0
 /// <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);
 }
示例#52
0
 /// <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));
        }
示例#56
0
        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();
            });
        }
示例#57
0
 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);
        }
示例#59
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="coord"></param>
 public void Filter(ICoordinate coord)
 {
     commonBitsX.Add(coord.X);
     commonBitsY.Add(coord.Y);
 }
示例#60
0
 /// <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)
 {
 }