Пример #1
0
        // Calculate the distance between two SimplePoints
        private static double Distance(SimplePoint p1, SimplePoint p2)
        {
            double result = 0;

            result = Math.Sqrt(Math.Pow((p2.x - p1.x), 2) + Math.Pow((p2.y - p1.y), 2));
            return(result);
        }
Пример #2
0
        public void TwoSimplePointsWithTheSameCoordinatesShouldBeConsideredTheSame()
        {
            var simplePoint1 = new SimplePoint(10, 10);
            var simplePoint2 = new SimplePoint(10, 10);

            simplePoint1.Equals(simplePoint2).Should().Be(true);
        }
Пример #3
0
        public void SimplePoint_ConstructorTakingTwoDoubles_InitializeCoordinatesAccordingly()
        {
            var simplePoint = new SimplePoint(1.1, 2.2);

            Assert.Equal(1.1, simplePoint.X);
            Assert.Equal(2.2, simplePoint.Y);
        }
Пример #4
0
        /// <summary>
        /// Calculate the distance between two SimplePoints
        /// </summary>
        /// <param name="p1">first point</param>
        /// <param name="p2">second point</param>
        /// <returns>distance between two points</returns>
        private static double Distance(SimplePoint p1, SimplePoint p2)
        {
            double result = 0;

            result = Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
            return(result);
        }
Пример #5
0
        //Compute the distance from AB to C
        //if isSegment is true, AB is a segment, not a line.
        private static double LineToPointDistance2D(SimplePoint linePoint1, SimplePoint linePoint2, SimplePoint pointTest, bool isSegment = true)
        {
            if (linePoint1.X == linePoint1.X && linePoint1.Y == linePoint2.Y)
            {
                return(255);
            }

            var    pointA = new double[] { linePoint1.X, linePoint1.Y };
            var    pointB = new double[] { linePoint2.X, linePoint2.Y };
            var    pointC = new double[] { pointTest.X, pointTest.Y };
            double dist   = CrossProduct(pointA, pointB, pointC) / Distance(pointA, pointB);

            if (isSegment)
            {
                double dot1 = DotProduct(pointA, pointB, pointC);
                if (dot1 > 0)
                {
                    return(Distance(pointB, pointC));
                }

                double dot2 = DotProduct(pointB, pointA, pointC);
                if (dot2 > 0)
                {
                    return(Distance(pointA, pointC));
                }
            }

            return(Math.Abs(dist));
        }
Пример #6
0
        public void SimplePoint_ParameterlessConstructor_InitializeZeroCoordinates()
        {
            var simplePoint = new SimplePoint();

            Assert.Equal(0, simplePoint.X);
            Assert.Equal(0, simplePoint.Y);
        }
Пример #7
0
        /// <summary>
        /// calculate center of circle and radius using three points
        /// </summary>
        /// <param name="p1">first point</param>
        /// <param name="p2">second point</param>
        /// <param name="p3">third point</param>
        /// <param name="circumCentre">center of circle</param>
        /// <param name="radius">value of radius</param>
        private static void CalculateCircumcircle(SimplePoint p1, SimplePoint p2, SimplePoint p3, out SimplePoint circumCentre, out double radius)
        {
            // Calculate the length of each side of the triangle
            double a = Distance(p2, p3); // side a is opposite point 1
            double b = Distance(p1, p3); // side b is opposite point 2
            double c = Distance(p1, p2); // side c is opposite point 3

            // Calculate the radius of the circumcircle
            double area = Math.Abs(((double)((p1.X * (p2.Y - p3.Y)) + (p2.X * (p3.Y - p1.Y)) + (p3.X * (p1.Y - p2.Y)))) / 2);
            radius = a * b * c / (4 * area);

            // Define area coordinates to calculate the circumcentre
            double pp1 = Math.Pow(a, 2) * (Math.Pow(b, 2) + Math.Pow(c, 2) - Math.Pow(a, 2));
            double pp2 = Math.Pow(b, 2) * (Math.Pow(c, 2) + Math.Pow(a, 2) - Math.Pow(b, 2));
            double pp3 = Math.Pow(c, 2) * (Math.Pow(a, 2) + Math.Pow(b, 2) - Math.Pow(c, 2));

            // Normalise
            double t1 = pp1 / (pp1 + pp2 + pp3);
            double t2 = pp2 / (pp1 + pp2 + pp3);
            double t3 = pp3 / (pp1 + pp2 + pp3);

            // Convert to Cartesian
            double x = (t1 * p1.X) + (t2 * p2.X) + (t3 * p3.X);
            double y = (t1 * p1.Y) + (t2 * p2.Y) + (t3 * p3.Y);

            circumCentre = new SimplePoint(x, y);
        }
Пример #8
0
        private static void CalculateCircumcircle(SimplePoint p1, SimplePoint p2, SimplePoint p3, out SimplePoint circumCentre, out double radius)
        {
            // Calculate the length of each side of the triangle
            double a = Distance(p2, p3); // side a is opposite point 1
            double b = Distance(p1, p3); // side b is opposite point 2
            double c = Distance(p1, p2); // side c is opposite point 3

            // Calculate the radius of the circumcircle
            double area = Math.Abs((double)(p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y)) / 2);

            radius = a * b * c / (4 * area);

            // Define area coordinates to calculate the circumcentre
            double pp1 = Math.Pow(a, 2) * (Math.Pow(b, 2) + Math.Pow(c, 2) - Math.Pow(a, 2));
            double pp2 = Math.Pow(b, 2) * (Math.Pow(c, 2) + Math.Pow(a, 2) - Math.Pow(b, 2));
            double pp3 = Math.Pow(c, 2) * (Math.Pow(a, 2) + Math.Pow(b, 2) - Math.Pow(c, 2));

            // Normalise
            double t1 = pp1 / (pp1 + pp2 + pp3);
            double t2 = pp2 / (pp1 + pp2 + pp3);
            double t3 = pp3 / (pp1 + pp2 + pp3);

            // Convert to Cartesian
            double x = t1 * p1.x + t2 * p2.x + t3 * p3.x;
            double y = t1 * p1.y + t2 * p2.y + t3 * p3.y;

            circumCentre = new SimplePoint(x, y);
        }
Пример #9
0
        protected void SetCenterMap(SimplePoint centerMap, bool animate)
        {
            // Take the point that we want to show, and center it on the client's UI.
            this.BeginInvoke(new Action(() =>
            {
                // The point that came in is raw on the map...
                var x = centerMap.X;
                var y = centerMap.Y;

                // We also need to account for the client's zoom factor (gives us the X/Y of a Zoomed map), to which we then "unzoom" the X/Y back to the raw map location for scroll purposes.
                x = (int)(((x * AssignedZoomFactor) - (this.VisibleSize.Width / 2.0d)) * this.InverseZoomFactor);
                y = (int)(((y * AssignedZoomFactor) - (this.VisibleSize.Height / 2.0d)) * this.InverseZoomFactor);

                if (!animate)
                {
                    SetScroll(x, y);
                    return;
                }

                // If we're already doing a Center Map fade, we're going to simply pop out the old values. It may glitch a bit to the end user, but the end result will be fine.
                // Our timer will go from True/0.0 to True/1.0, then flip to False/1.0 down to False/0.0
                this.centerMapFadingTimer.Tag = new SimplePoint(x, y);
                this.centerMapFadingValues    = new Tuple <bool, float>(true, 0.0f);
                this.centerMapFadingTimer.Start();
            }));
        }
Пример #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SimpleTriangle"/> struct
 /// </summary>
 /// <param name="a">index vertex a</param>
 /// <param name="b">index vertex b</param>
 /// <param name="c">index vertex c</param>
 /// <param name="circumcentre">center of triangle</param>
 /// <param name="radius">radius of triangle</param>
 public SimpleTriangle(int a, int b, int c, SimplePoint circumcentre, double radius)
 {
     this.A = a;
     this.B = b;
     this.C = c;
     this.CircumCentre = circumcentre;
     this.Radius = radius;
 }
Пример #11
0
 public SimpleTriangle(int a, int b, int c, SimplePoint circumcentre, double radius)
 {
     this.a            = a;
     this.b            = b;
     this.c            = c;
     this.circumcentre = circumcentre;
     this.radius       = radius;
 }
Пример #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SimpleTriangle"/> struct
 /// </summary>
 /// <param name="a">index vertex a</param>
 /// <param name="b">index vertex b</param>
 /// <param name="c">index vertex c</param>
 /// <param name="circumcentre">center of triangle</param>
 /// <param name="radius">radius of triangle</param>
 public SimpleTriangle(int a, int b, int c, SimplePoint circumcentre, double radius)
 {
     this.A            = a;
     this.B            = b;
     this.C            = c;
     this.CircumCentre = circumcentre;
     this.Radius       = radius;
 }
Пример #13
0
        void DrawConectionLines(SimplePoint leftop, SimplePoint rightop)
        {
            EndGatePoint = new SimplePoint {
                X = PortX, Y = PortY
            };

            var x2Input  = PortX + 7;
            var y2Input  = PortY + 20;
            var y22Input = PortY + 40;

            Polyline leftPolyline = new Polyline();

            leftPolyline.Stroke = Brushes.OrangeRed;
            PointCollection leftpoints = new PointCollection();


            leftpoints.Add(new Point {
                X = leftop.X - 2, Y = leftop.Y
            });
            leftpoints.Add(new Point {
                X = (x2Input + leftop.X) / 2.2, Y = leftop.Y
            });
            leftpoints.Add(new Point {
                X = (x2Input + leftop.X) / 2.2, Y = y2Input
            });
            leftpoints.Add(new Point {
                X = x2Input, Y = y2Input
            });
            leftPolyline.Points = leftpoints;



            Polyline rightPolyline = new Polyline();

            rightPolyline.Stroke = Brushes.OrangeRed;
            PointCollection rightpoints = new PointCollection();


            rightpoints.Add(new Point {
                X = rightop.X, Y = rightop.Y
            });
            rightpoints.Add(new Point {
                X = (x2Input + rightop.X) / 2.2 - 5, Y = rightop.Y
            });
            rightpoints.Add(new Point {
                X = (x2Input + rightop.X) / 2.2 - 5, Y = y22Input
            });
            rightpoints.Add(new Point {
                X = x2Input, Y = y22Input
            });
            rightPolyline.Points = rightpoints;



            CircuitField.Children.Add(leftPolyline);

            CircuitField.Children.Add(rightPolyline);
        }
Пример #14
0
        private static void SwapPoints(ref SimplePoint sp1, ref SimplePoint sp2)
        {
            sp1.X = 100;
            sp1.Y = 100;
            SimplePoint temp = sp1;

            sp1 = sp2;
            sp2 = temp;
        }
Пример #15
0
        public static void GeometryTriangulate(SqlGeometry MultiPoint)
        {
            List <SimplePoint> Vertices = new List <SimplePoint>();

            // Loop through supplied points
            for (int i = 1; i <= MultiPoint.STNumPoints(); i++)
            {
                //Create a new simple point corresponding to this element of the MultiPoint
                SimplePoint Point = new SimplePoint(
                    (double)MultiPoint.STPointN(i).STX,
                    (double)MultiPoint.STPointN(i).STY
                    );
                //Check whether this this point already exists
                if (!Vertices.Contains(Point))
                {
                    Vertices.Add(Point);
                }
            }
            Vertices.Sort();

            //Creating the Supertriangle
            SqlGeometry Envelope = MultiPoint.STEnvelope();
            //width
            double dx = (double)(Envelope.STPointN(2).STX - Envelope.STPointN(1).STX);
            //height
            double dy = (double)(Envelope.STPointN(4).STY - Envelope.STPointN(1).STY);
            // max dimension
            double dmax = (dx > dy) ? dx : dy;

            //Centre
            SqlGeometry centroid = Envelope.STCentroid();
            double      avgx     = (double)centroid.STX;
            double      avgy     = (double)centroid.STY;

            SimplePoint a = new SimplePoint(avgx - 2 * dmax, avgy - dmax);
            SimplePoint b = new SimplePoint(avgx + 2 * dmax, avgy - dmax);
            SimplePoint c = new SimplePoint(avgx, avgy + 2 * dmax);

            //Add the supertriangle to the end of the vertex array
            Vertices.Add(a);
            Vertices.Add(b);
            Vertices.Add(c);

            //create the supertringle
            double      radius;
            SimplePoint circumcentre;

            CalculateCircumcircle(a, b, c, out circumcentre, out radius);
            /////SimpleTriangle SuperTriangle = new SimpleTriangle(numPoints, numPoints + 1, numPoints + 2, circumcentre, radius);

            //Add the supertriangle
            List <SimpleTriangle> Triangles = new List <SimpleTriangle>();
            //////Triangles.Add(SimpleTriangle);

            //Create an empty list to hold completed triangles
            List <SimpleTriangle> CompletedTriangle = new List <SimpleTriangle>();
        }
Пример #16
0
        public void ShouldCreateASimplePointSucessfullyWithValidParameters()
        {
            var simplePoint = new SimplePoint(10, 10);

            simplePoint.Should().Not.Be.Null();
            simplePoint.GetType().Should().Be <SimplePoint>();
            simplePoint.X.Should().Be(10);
            simplePoint.Y.Should().Be(10);
        }
Пример #17
0
        public void WriteCenterMap(SimplePoint point)
        {
            if (ClientsCount == 0)
            {
                return;
            }

            EnqueueWrite(new CenterMapSocketObject(point));
        }
Пример #18
0
 public IEnumerable <BranchDto> QueryBranchesByCenterPoint(SimplePoint center, double buffer)
 {
     return(InAUnitOfWork(session =>
     {
         var geoLocator = new GeoLocator(session);
         var geoPoint = _mappingEngine.Map <SimplePoint, Point>(center);
         var results = geoLocator.Locate <Branch>(geoPoint, buffer);
         return results.Select(r => _mappingEngine.Map <Branch, BranchDto>(r)).ToList();
     }));
 }
        public async Task <ICollection <CrowdsourcedPlace> > GetClosePlaces(SimplePoint start, SimplePoint end)
        {
            var query = new SpatialViewQuery().From("doc", "crowdsourcedpoints")
                        .Stale(StaleState.False)
                        .StartRange(start.Longitude, start.Latitude)
                        .EndRange(end.Longitude, end.Latitude);

            var result = await _bucket.QueryAsync <CrowdsourcedPlace>(query);

            return(result.Rows.Select(x => x.Value).ToList());
        }
        public async Task <IEnumerable <CrowdsourcedPlace> > Get(
            [FromQuery] double leftBottomX,
            [FromQuery] double leftBottomY,
            [FromQuery] double rightTopX,
            [FromQuery] double rightTopY)
        {
            var leftBottom = new SimplePoint(leftBottomX, leftBottomY);
            var rightTop   = new SimplePoint(rightTopX, rightTopY);

            return(await _crowdsourcedPlacesService.GetClosePlaces(leftBottom, rightTop));
        }
Пример #21
0
        public void ShouldCreateAProperArrayWithCoordinates()
        {
            var simplePoint = new SimplePoint(15, 30);

            var simplePointArray = simplePoint.ToArray();

            simplePointArray.Should().Not.Be.Null();
            simplePointArray.Length.Should().Be(2);
            simplePointArray[0].Should().Be(15);
            simplePointArray[1].Should().Be(30);
        }
Пример #22
0
        public void IsTheSame_ProvidingDifferentPoints_ReturnsFalse()
        {
            //Arrange
            SimplePoint simplePoint1 = new SimplePoint(0, 0);
            SimplePoint simplePoint2 = new SimplePoint(10, 10);

            //Act
            var result = simplePoint1.IsTheSame(simplePoint2, 3);

            //Assert
            Assert.False(result);
        }
Пример #23
0
        public void IsTheSame_ProvidingTheSamePoints_ReturnsTrue()
        {
            //Arrange
            SimplePoint simplePoint1 = new SimplePoint(0, 0);
            SimplePoint simplePoint2 = new SimplePoint(0, 0);

            //Act
            var result = simplePoint1.IsTheSame(simplePoint2, 3);

            //Assert
            Assert.True(result);
        }
Пример #24
0
        public void Distance_InsertSimplePoint_ReturnsDistanceToSimplePoint()
        {
            //Arrange
            SimplePoint simplePoint1   = new SimplePoint(0, 0);
            SimplePoint simplePoint2   = new SimplePoint(1, 1);
            var         expectedResult = Math.Sqrt(2);

            //Act
            var result = simplePoint1.Distance(simplePoint2);

            //Assert
            Assert.True((bool)(Math.Abs(result - expectedResult) < Double.Epsilon));
        }
Пример #25
0
        static void Main(string[] args)
        {
            //CustomConsoleExample();

            var encoded = GetCodePoint('S');

            BinaryFormatterTest.Test();

            Console.ReadKey();

            ActivityHandler activityHandler = new ActivityHandler();

            activityHandler.WriteActivityStateInternal();

            activityHandler.ReadActivityState();

            Console.ReadKey();

            int intVal1 = 1;
            int intVal2 = 2;

            Console.WriteLine("Integers before regular swap method: {0} & {1}", intVal1, intVal2);
            SwapIntegers(intVal1, intVal2);
            Console.WriteLine("Integers after regular swap method: {0} & {1}", intVal1, intVal2);
            SwapIntegersByRef(ref intVal1, ref intVal2);
            Console.WriteLine("Integers after ref swap method: {0} & {1}", intVal1, intVal2);
            Console.ReadKey();

            PrintRedLine();

            SimplePoint sp1 = new SimplePoint();
            SimplePoint sp2 = new SimplePoint();

            Console.WriteLine("Points before swap method: {0} & {1}", sp1, sp2);
            SwapPoints(sp1, sp2);
            Console.WriteLine("Points after swap method: {0} & {1}", sp1, sp2);
            SwapPoints(ref sp1, ref sp2);
            Console.WriteLine("Points after ref swap method: {0} & {1}", sp1, sp2);

            PrintRedLine();

            Type intListType    = typeof(List <int>);
            Type stringListType = typeof(List <string>);

            Console.WriteLine("intList type = " + intListType.ToString());
            Console.WriteLine("stringList type = " + stringListType.FullName);

            Console.WriteLine();
            Console.WriteLine("Press any key to quit...");
            Console.ReadKey();
        }
Пример #26
0
        // Construct a triangle from 3 vertices
        private static SqlGeometry TriangleFromPoints(SimplePoint p1, SimplePoint p2, SimplePoint p3, int srid)
        {
            SqlGeometryBuilder TriangleBuilder = new SqlGeometryBuilder();

            TriangleBuilder.SetSrid(srid);
            TriangleBuilder.BeginGeometry(OpenGisGeometryType.Polygon);
            TriangleBuilder.BeginFigure(p1.x, p1.y);
            TriangleBuilder.AddLine(p2.x, p2.y);
            TriangleBuilder.AddLine(p3.x, p3.y);
            TriangleBuilder.AddLine(p1.x, p1.y);
            TriangleBuilder.EndFigure();
            TriangleBuilder.EndGeometry();
            return(TriangleBuilder.ConstructedGeometry);
        }
Пример #27
0
            /// <summary>
            /// Implement IComparable CompareTo method to enable sorting
            /// </summary>
            /// <param name="obj">object simple point</param>
            /// <returns>value of compare</returns>
            int IComparable.CompareTo(object obj)
            {
                SimplePoint other = (SimplePoint)obj;

                if (this.X > other.X)
                {
                    return(1);
                }
                else if (this.X < other.X)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                }
            }
Пример #28
0
        public SimplePoint DrawAndPort(SimplePoint leftop, SimplePoint rightop)
        {
            ANDControl andControl = new ANDControl();

            Canvas.SetLeft(andControl, PortX);
            Canvas.SetTop(andControl, PortY);

            CircuitField.Children.Add(andControl);

            DrawConectionLines(leftop, rightop);
            var con = new SimplePoint {
                X = PortX + LogicGateWidth, Y = PortY + LogicGateHeight / 2
            };

            IncrementGatesCordinate();
            return(con);
        }
Пример #29
0
        public SimplePoint DrawNotPort(SimplePoint expPoint)
        {
            NotControl notControl = new NotControl();

            Canvas.SetLeft(notControl, expPoint.X - 5);
            Canvas.SetTop(notControl, expPoint.Y - (NotGateSize / 2));

            CircuitField.Children.Add(notControl);

            if (EndGatePoint != null)
            {
                EndGatePoint.X += notControl.Width;
            }

            return(new SimplePoint {
                X = expPoint.X + notControl.Width, Y = expPoint.Y
            });
        }
Пример #30
0
        public static ILocation CircularLocation(int start, int end, Strand strand, int length)
        {
            int min = Math.Min(start, end);
            int max = Math.Max(start, end);

            bool isReverse = (min != start);

            if (min > length)
            {
                throw new ArgumentException("Cannot process a "
                                            + "location whose lowest coordinate is less than "
                                            + "the given length " + length);
            }

            if (max <= length)
            {
                return(Location(start, end, strand, length));
            }

            int modStart       = ModulateCircularIndex(start, length);
            int modEnd         = ModulateCircularIndex(end, length);
            int numberOfPasses = CompleteCircularPasses(Math.Max(start, end), length);

            if (isReverse)
            {
                int reversedModStart = new SimplePoint(modStart).Reverse(length).GetPosition();
                int reversedModEnd   = new SimplePoint(modEnd).Reverse(length).GetPosition();
                modStart = reversedModStart;
                modEnd   = reversedModEnd;
                start    = reversedModStart;
                end      = (length * (numberOfPasses + 1)) + modEnd;
            }

            List <ILocation> locations = new List <ILocation>();

            locations.Add(new SimpleLocation(modStart, length, strand));
            for (int i = 0; i < numberOfPasses; i++)
            {
                locations.Add(new SimpleLocation(1, length, strand));
            }
            locations.Add(new SimpleLocation(1, modEnd, strand));
            return(new SimpleLocation(new SimplePoint(start),
                                      new SimplePoint(end), strand, true, false, locations));
        }
Пример #31
0
        public SimplePoint DrawVariable(char name)
        {
            Switch sw = new Switch(name);



            Canvas.SetLeft(sw, 10);
            Canvas.SetTop(sw, VariableY);
            var         x1 = 10 + SwitchWidth;
            var         y1 = VariableY + SwitchHeight / 2;
            SimplePoint p  = new SimplePoint {
                X = x1, Y = y1
            };

            VariableY += (int)sw.Height + 20;
            CircuitField.Children.Add(sw);

            return(p);
        }
Пример #32
0
 /// <summary>
 /// Calculate the distance between two SimplePoints
 /// </summary>
 /// <param name="p1">first point</param>
 /// <param name="p2">second point</param>
 /// <returns>distance between two points</returns>
 private static double Distance(SimplePoint p1, SimplePoint p2)
 {
     double result = 0;
     result = Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
     return result;
 }
Пример #33
0
        public static void GeometryTriangulate(SqlGeometry MultiPoint)
        {
            // Retrieve the SRID
            int srid = (int)MultiPoint.STSrid;

            // Check valid input
            if (!(MultiPoint.STGeometryType() == "MULTIPOINT" && MultiPoint.STNumPoints() > 3))
            {
                throw new ArgumentException("Input must be a MultiPoint containing at least three points");
            }

            // Initialise a list of vertices
            List <SimplePoint> Vertices = new List <SimplePoint>();

            // Add all the original supplied points
            for (int i = 1; i <= MultiPoint.STNumPoints(); i++)
            {
                SimplePoint Point = new SimplePoint((double)MultiPoint.STPointN(i).STX, (double)MultiPoint.STPointN(i).STY);
                // MultiPoints can contain the same point twice, but this messes up Delauney
                if (!Vertices.Contains(Point))
                {
                    Vertices.Add(Point);
                }
            }

            // Important - count the number of points in the array, NOT using STNumPoints of the supplied geometry, as some duplicate points
            // may have been removed
            int numPoints = Vertices.Count;

            // Sort the list so that points sweep from left - right
            Vertices.Sort();

            // Calculate the "supertriangle" that encompasses the pointset
            SqlGeometry Envelope = MultiPoint.STEnvelope();
            // Width
            double dx = (double)(Envelope.STPointN(2).STX - Envelope.STPointN(1).STX);
            // Height
            double dy = (double)(Envelope.STPointN(4).STY - Envelope.STPointN(1).STY);
            // Maximum dimension
            double dmax = (dx > dy) ? dx : dy;
            // Centre
            double avgx = (double)Envelope.STCentroid().STX;
            double avgy = (double)Envelope.STCentroid().STY;
            // Create the points at corners of the supertriangle
            SimplePoint a = new SimplePoint(avgx - 2 * dmax, avgy - dmax);
            SimplePoint b = new SimplePoint(avgx + 2 * dmax, avgy - dmax);
            SimplePoint c = new SimplePoint(avgx, avgy + 2 * dmax);

            // Add the supertriangle vertices to the end of the vertex array
            Vertices.Add(a);
            Vertices.Add(b);
            Vertices.Add(c);

            double      radius;
            SimplePoint circumcentre;

            CalculateCircumcircle(a, b, c, out circumcentre, out radius);

            // Create a triangle from the vertices
            SimpleTriangle SuperTriangle = new SimpleTriangle(numPoints, numPoints + 1, numPoints + 2, circumcentre, radius);

            // Add the supertriangle to the list of triangles
            List <SimpleTriangle> Triangles = new List <SimpleTriangle>();

            Triangles.Add(SuperTriangle);

            List <SimpleTriangle> CompletedTriangles = new List <SimpleTriangle>();

            // Loop through each point
            for (int i = 0; i < numPoints; i++)
            {
                // Initialise the edge buffer
                List <int[]> Edges = new List <int[]>();

                // Loop through each triangle
                for (int j = Triangles.Count - 1; j >= 0; j--)
                {
                    // If the point lies within the circumcircle of this triangle
                    if (Distance(Triangles[j].circumcentre, Vertices[i]) < Triangles[j].radius)
                    {
                        // Add the triangle edges to the edge buffer
                        Edges.Add(new int[] { Triangles[j].a, Triangles[j].b });
                        Edges.Add(new int[] { Triangles[j].b, Triangles[j].c });
                        Edges.Add(new int[] { Triangles[j].c, Triangles[j].a });

                        // Remove this triangle from the list
                        Triangles.RemoveAt(j);
                    }

                    // If this triangle is complete
                    else if (Vertices[i].x > Triangles[j].circumcentre.x + Triangles[j].radius)
                    {
                        CompletedTriangles.Add(Triangles[j]);
                        Triangles.RemoveAt(j);
                    }
                }

                // Remove duplicate edges
                for (int j = Edges.Count - 1; j > 0; j--)
                {
                    for (int k = j - 1; k >= 0; k--)
                    {
                        // Compare if this edge matches in either direction
                        if (Edges[j][0].Equals(Edges[k][1]) && Edges[j][1].Equals(Edges[k][0]))
                        {
                            // Remove both duplicates
                            Edges.RemoveAt(j);
                            Edges.RemoveAt(k);

                            // We've removed an item from lower down the list than where j is now, so update j
                            j--;
                            break;
                        }
                    }
                }

                // Create new triangles for the current point
                for (int j = 0; j < Edges.Count; j++)
                {
                    CalculateCircumcircle(Vertices[Edges[j][0]], Vertices[Edges[j][1]], Vertices[i], out circumcentre, out radius);
                    SimpleTriangle T = new SimpleTriangle(Edges[j][0], Edges[j][1], i, circumcentre, radius);
                    Triangles.Add(T);
                }
            }

            // We've finished triangulation. Move any remaining triangles onto the completed list
            CompletedTriangles.AddRange(Triangles);

            // Define the metadata of the results column
            SqlMetaData metadata = new SqlMetaData("Triangle", SqlDbType.Udt, typeof(SqlGeometry));

            // Create a record based on this metadata
            SqlDataRecord record = new SqlDataRecord(metadata);

            // Send the results back to the client
            SqlContext.Pipe.SendResultsStart(record);
            foreach (SimpleTriangle Tri in CompletedTriangles)
            {
                // Check that this is a triangle formed only from vertices in the original multipoint
                // i.e. not from the vertices of the supertriangle.
                if (Tri.a < numPoints && Tri.b < numPoints && Tri.c < numPoints)
                {
                    SqlGeometry triangle = TriangleFromPoints(Vertices[Tri.a], Vertices[Tri.b], Vertices[Tri.c], srid);
                    record.SetValue(0, triangle);
                    SqlContext.Pipe.SendResultsRow(record);
                }
            }
            SqlContext.Pipe.SendResultsEnd();
        }
Пример #34
0
        /// <summary>
        /// Calculate diagram voronoi from list of points
        /// </summary>
        /// <param name="points">list of points</param>
        /// <returns>list of polygons</returns>
        public static IList<IGeometry> GeometryVoronoi(List<IPoint> points)
        {
            // Check valid input
            if (points.Count < 3)
            {
                throw new ArgumentException("Input must be a MultiPoint containing at least three points");
            }

            // Initialise a list of vertices
            List<SimplePoint> vertices = new List<SimplePoint>();

            // Add all the original supplied points
            for (int i = 0; i < points.Count; i++)
            {
                SimplePoint point = new SimplePoint(points[i].X, points[i].Y);

                // MultiPoints can contain the same point twice, but this messes up Delaunay
                if (!vertices.Contains(point))
                {
                    vertices.Add(point);
                }
            }

            // Important - count the number of points in the array as some duplicate points
            // may have been removed
            int numPoints = vertices.Count;

            // Check valid input
            if (numPoints < 3)
            {
                throw new ArgumentException("Input must be a list of points containing at least three points");
            }

            // Important! Sort the list so that points sweep from left - right
            vertices.Sort();

            IPointCollection pointCollection = new MultipointClass();
            foreach (SimplePoint p in vertices)
            {
                pointCollection.AddPoint(new PointClass() { X = p.X, Y = p.Y });
            }

            // Calculate the "supertriangle" that encompasses the pointset
            IEnvelope envelope = (pointCollection as IGeometry).Envelope;

            // Width
            double dx = envelope.Width;

            // Height
            double dy = envelope.Height;

            // Maximum dimension
            double dmax = (dx > dy) ? dx : dy;

            // Centre
            double avgx = ((envelope.XMax - envelope.XMin) / 2) + envelope.XMin;
            double avgy = ((envelope.YMax - envelope.YMin) / 2) + envelope.YMin;

            // Create the points at corners of the supertriangle
            SimplePoint a = new SimplePoint(avgx - (2 * dmax), avgy - dmax);
            SimplePoint b = new SimplePoint(avgx + (2 * dmax), avgy - dmax);
            SimplePoint c = new SimplePoint(avgx, avgy + (2 * dmax));

            // Add the supertriangle vertices to the end of the vertex array
            vertices.Add(a);
            vertices.Add(b);
            vertices.Add(c);

            double radius;
            SimplePoint circumcentre;
            Triangulation.CalculateCircumcircle(a, b, c, out circumcentre, out radius);

            // Create a triangle from the vertices
            SimpleTriangle superTriangle = new SimpleTriangle(numPoints, numPoints + 1, numPoints + 2, circumcentre, radius);

            // Add the supertriangle to the list of triangles
            List<SimpleTriangle> triangles = new List<SimpleTriangle>();
            triangles.Add(superTriangle);

            List<SimpleTriangle> completedTriangles = new List<SimpleTriangle>();

            // Loop through each point
            for (int i = 0; i < numPoints; i++)
            {
                // Initialise the edge buffer
                List<int[]> edges = new List<int[]>();

                // Loop through each triangle
                for (int j = triangles.Count - 1; j >= 0; j--)
                {
                    // If the point lies within the circumcircle of this triangle
                    if (Distance(triangles[j].CircumCentre, vertices[i]) < triangles[j].Radius)
                    {
                        // Add the triangle edges to the edge buffer
                        edges.Add(new int[] { triangles[j].A, triangles[j].B });
                        edges.Add(new int[] { triangles[j].B, triangles[j].C });
                        edges.Add(new int[] { triangles[j].C, triangles[j].A });

                        // Remove this triangle from the list
                        triangles.RemoveAt(j);
                    }
                    else if (vertices[i].X > triangles[j].CircumCentre.X + triangles[j].Radius)
                    {
                        // If this triangle is complete
                        {
                            completedTriangles.Add(triangles[j]);
                        }

                        triangles.RemoveAt(j);
                    }
                }

                // Remove duplicate edges
                for (int j = edges.Count - 1; j > 0; j--)
                {
                    for (int k = j - 1; k >= 0; k--)
                    {
                        // Compare if this edge match in either direction
                        if (edges[j][0].Equals(edges[k][1]) && edges[j][1].Equals(edges[k][0]))
                        {
                            // Remove both duplicates
                            edges.RemoveAt(j);
                            edges.RemoveAt(k);

                            // We've removed an item from lower down the list than where j is now, so update j
                            j--;
                            break;
                        }
                    }
                }

                // Create new triangles for the current point
                for (int j = 0; j < edges.Count; j++)
                {
                    Triangulation.CalculateCircumcircle(vertices[edges[j][0]], vertices[edges[j][1]], vertices[i], out circumcentre, out radius);
                    SimpleTriangle t = new SimpleTriangle(edges[j][0], edges[j][1], i, circumcentre, radius);
                    triangles.Add(t);
                }
            }

            // We've finished triangulation. Move any remaining triangles onto the completed list
            completedTriangles.AddRange(triangles);

            IList<IGeometry> voronoiPolygon = new List<IGeometry>();
            for (var i = 0; i < vertices.Count; i++)
            {
                // Initiliase a new geometry to hold the voronoi polygon
                IPointCollection mp = new MultipointClass();

                // Look through each triangle
                foreach (SimpleTriangle tri in completedTriangles)
                {
                    // If the triangle intersects this point
                    if (tri.A == i || tri.B == i || tri.C == i)
                    {
                        mp.AddPoint(new PointClass() { X = tri.CircumCentre.X, Y = tri.CircumCentre.Y });
                    }
                }

                // Create the voronoi polygon from the convex hull of the circumcentres of intersecting triangles
                ITopologicalOperator topologicalOperator = mp as ITopologicalOperator;
                IGeometry polygon = topologicalOperator.ConvexHull();
                topologicalOperator = polygon as ITopologicalOperator;
                IGeometry result = topologicalOperator.Intersect(envelope, esriGeometryDimension.esriGeometry2Dimension);
                if ((result != null) && (!result.IsEmpty))
                {
                    voronoiPolygon.Add(result);
                }
            }

            return voronoiPolygon;
        }