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); }
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); }
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; } }