Пример #1
0
        public void CoordinateAngleTest()
        {
            // test case 1: 90°
            Coordinate origin = new Coordinate(0, 0);
            Coordinate first  = new Coordinate(1, 0);
            Coordinate second = new Coordinate(0, 1);

            Assert.AreEqual(Math.PI / 2, Coordinate.Angle(origin, first, second), 0.00001);

            // test case 2: 180°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(-1, 0);

            Assert.AreEqual(Math.PI, Coordinate.Angle(origin, first, second), 0.00001);

            // test case 3: -180°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(-1, 0);
            second = new Coordinate(1, 0);

            Assert.AreEqual(Math.PI, Coordinate.Angle(origin, first, second), 0.00001);

            // test case 4: 45°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(1, 1);

            Assert.AreEqual(Math.PI / 4, Coordinate.Angle(origin, first, second), 0.00001);

            // test case 5: 60°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(1, Math.Sqrt(3));

            Assert.AreEqual(Math.PI / 3, Coordinate.Angle(origin, first, second), 0.00001);
        }
Пример #2
0
        public void CoordinateAngleTest()
        {
            // 90°
            Coordinate origin = new Coordinate(0, 0);
            Coordinate first  = new Coordinate(1, 0);
            Coordinate second = new Coordinate(0, 1);

            Coordinate.Angle(origin, first, second).ShouldBe(Math.PI / 2, 0.00001);

            // 180°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(-1, 0);

            Coordinate.Angle(origin, first, second).ShouldBe(Math.PI, 0.00001);

            // -180°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(-1, 0);
            second = new Coordinate(1, 0);

            Coordinate.Angle(origin, first, second).ShouldBe(Math.PI, 0.00001);

            // 45°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(1, 1);

            Coordinate.Angle(origin, first, second).ShouldBe(Math.PI / 4, 0.00001);

            // 60°
            origin = new Coordinate(0, 0);
            first  = new Coordinate(1, 0);
            second = new Coordinate(1, Math.Sqrt(3));

            Coordinate.Angle(origin, first, second).ShouldBe(Math.PI / 3, 0.00001);
        }
Пример #3
0
 static public float MapAngleBetween(Coordinate a, Coordinate b)
 {
     return(a.Angle(b));;
 }
        /// <summary>
        /// Computes the result of the operation.
        /// </summary>
        protected override void ComputeResult()
        {
            switch (_dimension)
            {
            case 0:
                foreach (IGraphVertex vertex in Source.Vertices)
                {
                    _points.Add(_factory.CreatePoint(vertex.Coordinate, _metadataPreservation ? vertex.Metadata : null));
                }
                break;

            case 1:
                foreach (IGraphVertex vertex in Source.Vertices)
                {
                    _points.Add(_factory.CreatePoint(vertex.Coordinate, _metadataPreservation ? vertex.Metadata : null));
                }

                foreach (IGraphVertex vertex in Source.Vertices)
                {
                    foreach (IGraphEdge edge in Source.OutEdges(vertex))
                    {
                        if (edge.Source.Coordinate.Equals(edge.Target.Coordinate))
                        {
                            continue;
                        }
                        _points.Remove(_factory.CreatePoint(edge.Source.Coordinate));
                        _points.Remove(_factory.CreatePoint(edge.Target.Coordinate));
                        _lines.Add(_factory.CreateLine(edge.Source.Coordinate, edge.Target.Coordinate, _metadataPreservation ? edge.Metadata : null));
                    }
                }
                break;

            case 2:
                // source: Jiang, X. Y., Bunke, H.: An optimal algorithm for extracting the regions of a plane graph (1993)

                List <Coordinate> coordinates = new List <Coordinate>();

                // find all wedges
                List <AngularEdge> edges = new List <AngularEdge>();

                foreach (IGraphVertex vertex in Source.Vertices)
                {
                    Coordinate sourceCoordinate = vertex.Coordinate;
                    Coordinate baseCoordinate   = vertex.Coordinate - new CoordinateVector(1, 0);

                    IEnumerable <IGraphEdge> outEdges = Source.OutEdges(vertex);

                    if (outEdges.Count() == 0)
                    {
                        coordinates.Add(vertex.Coordinate);
                        continue;
                    }
                    foreach (IGraphEdge edge in outEdges)
                    {
                        Coordinate target = edge.Target.Coordinate;

                        edges.Add(new AngularEdge(sourceCoordinate, target,
                                                  Coordinate.Orientation(sourceCoordinate, baseCoordinate, target) == Orientation.CounterClockwise ?
                                                  Coordinate.Angle(sourceCoordinate, baseCoordinate, target) :
                                                  Math.PI - Coordinate.Angle(sourceCoordinate, baseCoordinate, target)));
                    }
                }

                edges.Sort(new AngularEdgeComparer());

                IEnumerable <IGrouping <Coordinate, AngularEdge> > groups = edges.GroupBy(angularEdge => angularEdge.Source);

                List <Wedge> wedges = new List <Wedge>();

                foreach (IGrouping <Coordinate, AngularEdge> group in groups)
                {
                    AngularEdge[] groupEdges = group.ToArray();
                    for (Int32 i = 0; i < groupEdges.Length - 1; i++)
                    {
                        wedges.Add(new Wedge(groupEdges[i + 1].Target, groupEdges[i].Source, groupEdges[i].Target));
                    }
                    wedges.Add(new Wedge(groupEdges[0].Target, groupEdges[0].Source, groupEdges[groupEdges.Length - 1].Target));
                }

                // grouping wedges to regions
                List <List <Wedge> > faces         = new List <List <Wedge> >();
                List <List <Wedge> > leftOverEdges = new List <List <Wedge> >();

                for (Int32 i = 0; i < wedges.Count; i++)
                {
                    List <Wedge> wedgeSeries = new List <Wedge>();

                    Wedge currentWedge = wedges[i];

                    do
                    {
                        wedges.Remove(currentWedge);
                        wedgeSeries.Add(currentWedge);

                        currentWedge = wedges.FirstOrDefault(wedge => wedge.First.Equals(currentWedge.Second) && wedge.Second.Equals(currentWedge.Third));
                    }while (currentWedge != null);

                    if (wedgeSeries[0].First.Equals(wedgeSeries[wedgeSeries.Count - 1].Second) && wedgeSeries[0].Second.Equals(wedgeSeries[wedgeSeries.Count - 1].Third))
                    {
                        faces.Add(wedgeSeries);
                    }
                    else
                    {
                        leftOverEdges.Add(wedgeSeries);
                    }
                }

                for (Int32 i = 0; i < faces.Count; i++)
                {
                    List <Coordinate> shell = faces[i].Select(wedge => wedge.First).ToList();
                    shell.Add(shell[0]);

                    if (PolygonAlgorithms.Orientation(shell) == Orientation.CounterClockwise)
                    {
                        Dictionary <String, Object> metadata = null;
                        if (_metadataPreservation)
                        {
                            metadata = new Dictionary <String, Object>();

                            foreach (IMetadataCollection collection in shell.Select(coordinate => Source.GetVertex(coordinate).Metadata))
                            {
                                foreach (String key in collection.Keys)
                                {
                                    metadata[key] = collection[key];
                                }
                            }
                        }

                        _polygons.Add(_factory.CreatePolygon(shell, metadata));
                    }
                }

                for (Int32 i = 0; i < leftOverEdges.Count; i++)
                {
                    for (Int32 j = 0; j < leftOverEdges[i].Count; j++)
                    {
                        _lines.Add(_factory.CreateLine(leftOverEdges[i][j].First,
                                                       leftOverEdges[i][j].Second,
                                                       _metadataPreservation ? Source.GetEdge(leftOverEdges[i][j].First, leftOverEdges[i][j].Second).Metadata : null));
                    }
                }

                foreach (Coordinate coordinate in coordinates)
                {
                    _points.Add(_factory.CreatePoint(coordinate,
                                                     _metadataPreservation ? Source.GetVertex(coordinate).Metadata : null));
                }
                break;
            }
        }