コード例 #1
0
        /// <summary>
        /// We distinguish five types of vertices. Four of these types are
        /// turn vertices. They are defined as follows: A vertex v is a
        /// start vertex if its two neighbours lie below it and the interior
        /// angle at v is less the pi; if the interior angle is greater than
        /// pi then v is a split vertex. (if both neighbours lie below v,
        /// then the interior angle cannot be exacly pi.  A vertex is an end
        /// vertex if its two neighbours lie above it and the intertior angle
        ///  at v is less that pi; if the interior angle is greater than pi
        /// then v is a merge vertex. The vertices that are not turn vertices
        /// are regular vertices. Thus a regular vertex has one of its
        /// neighbours above it and one below it. These names have been chosen
        /// because the algorithm will use a downward plane sweep.
        /// </summary>
        /// <param name="vb">The vertex whose type is to be determined</param>
        /// <returns>The type of the vertex</returns>
        private VertexType GetVertexType(TVertex vb)
        {
            // TODO: Only works for polygons!
            Debug.Assert(vb.Degree == 2);
            // TODO: Make this more efficient
            VertexBase va = vb.Edges.First().Target;
            VertexBase vc = vb.Edges.Last().Target;

            Point2D a = ((IPositioned2D)va).Position;
            Point2D b = vb.Position;
            Point2D c = ((IPositioned2D)vc).Position;

            if (yComparer.Compare(a, b) == 0 && yComparer.Compare(c, b) == 0)
            {
                return(VertexType.Collinear);
            }

            if (yxComparer.Compare(a, b) < 0)
            {
                if (yxComparer.Compare(c, b) < 0)
                {
                    return(LeftTurn(a, b, c) ? VertexType.Start : VertexType.Split);
                }
                return(VertexType.Regular);
            }
            if (yxComparer.Compare(b, c) < 0)
            {
                return(LeftTurn(a, b, c) ? VertexType.End : VertexType.Merge);
            }
            return(VertexType.Regular);
        }
コード例 #2
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void BracedQuadilateral()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();
            VertexBase vC = new VertexBase();
            VertexBase vD = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            mesh.Add(vC);
            mesh.Add(vD);

            EdgeBase eA    = mesh.AddEdge(vA, vB);
            EdgeBase eB    = mesh.AddEdge(vB, vC);
            EdgeBase eC    = mesh.AddEdge(vC, vD);
            EdgeBase eD    = mesh.AddEdge(vD, vA);
            EdgeBase brace = mesh.AddEdge(vA, vC);

            Assert.AreNotSame(eA, eB);
            Assert.AreNotSame(eB, eC);
            Assert.AreNotSame(eC, eD);
            Assert.AreNotSame(eD, eA);
            Assert.AreNotEqual(eA, brace);
            Assert.AreEqual(4, mesh.VertexCount);
            Assert.AreEqual(5, mesh.EdgeCount);
            Assert.AreEqual(0, mesh.FaceCount);
            Assert.AreEqual(3, vA.Degree);
            Assert.AreEqual(2, vB.Degree);
            Assert.AreEqual(3, vC.Degree);
            Assert.AreEqual(2, vD.Degree);
        }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="control"></param>
        /// <param name="toggle"></param>
        public virtual void SelectVertex(VertexControl control, bool toggle)
        {
            if (control == null)
            {
                return;
            }

            VertexBase vertex = (VertexBase)control.Vertex;

            if (selected_vertices_.Contains(vertex))
            {
                if (toggle)
                {
                    control.SetValue(Selector.IsSelectedProperty, false);
                    DragBehaviour.SetIsTagged(control, false);

                    selected_vertices_.Remove(vertex);
                    vertex_controls_.Remove(vertex);
                }
            }
            else
            {
                control.SetValue(Selector.IsSelectedProperty, true);
                DragBehaviour.SetIsTagged(control, true);

                selected_vertices_.Add(vertex);
                vertex_controls_.Add(vertex, control);
            }
        }
コード例 #4
0
 void RestoreStoreDataInVertexes()
 {
     foreach (IVertex v in VertexIdentifiersDictionary.Values)
     {
         VertexBase vb = (VertexBase)v;
         vb._store = this;
     }
 }
コード例 #5
0
 void NullStoreDataInVertexes()
 {
     foreach (IVertex v in VertexIdentifiersDictionary.Values)
     {
         VertexBase vb = (VertexBase)v;
         vb._store = null;
     }
 }
コード例 #6
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void SingleIsolatedVertex()
        {
            VertexBase vA = new VertexBase();

            mesh.Add(vA);
            Assert.AreEqual(1, mesh.VertexCount);
            Assert.IsTrue(vA.IsIsolated);
        }
コード例 #7
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void TwoIsolatedVertices()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            Assert.AreEqual(2, mesh.VertexCount);
            Assert.IsTrue(vA.IsIsolated);
            Assert.IsTrue(vB.IsIsolated);
        }
コード例 #8
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public virtual VertexBase <T> Other(VertexBase <T> vertex)
 {
     if (vertex == From)
     {
         return(To);
     }
     if (vertex == To)
     {
         return(From);
     }
     return(null);
 }
コード例 #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="control"></param>
        public virtual void UnselectVertex(VertexControl control)
        {
            if (control == null)
            {
                return;
            }

            VertexBase vertex = (VertexBase)control.Vertex;

            control.SetValue(Selector.IsSelectedProperty, false);
            DragBehaviour.SetIsTagged(control, false);

            selected_vertices_.Remove(vertex);
            vertex_controls_.Remove(vertex);
        }
コード例 #10
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void DuplicateEdge()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            EdgeBase edge1       = new EdgeBase();
            EdgeBase actualEdge1 = mesh.AddEdge(vA, vB, edge1);
            EdgeBase edge2       = new EdgeBase();
            EdgeBase actualEdge2 = mesh.AddEdge(vA, vB, edge2);

            Assert.AreSame(edge1, actualEdge1);
            Assert.AreSame(actualEdge1, actualEdge2);
            Assert.AreNotSame(edge2, actualEdge2);
        }
コード例 #11
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void SingleEdge()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            EdgeBase edge       = new EdgeBase();
            EdgeBase actualEdge = mesh.AddEdge(vA, vB, edge);

            Assert.AreEqual(2, mesh.VertexCount);
            Assert.AreEqual(1, mesh.EdgeCount);
            Assert.IsFalse(vA.IsIsolated);
            Assert.IsFalse(vB.IsIsolated);
            Assert.AreSame(edge, actualEdge);
            Assert.AreSame(vA, edge.Source);
            Assert.AreSame(vB, edge.Target);
        }
コード例 #12
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void Tetrahedron()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();
            VertexBase vC = new VertexBase();
            VertexBase vD = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            mesh.Add(vC);
            mesh.Add(vD);

            EdgeBase e1 = mesh.AddEdge(vA, vB);
            EdgeBase e2 = mesh.AddEdge(vB, vC);
            EdgeBase e3 = mesh.AddEdge(vC, vA);
            EdgeBase e4 = mesh.AddEdge(vA, vD);
            EdgeBase e5 = mesh.AddEdge(vB, vD);
            EdgeBase e6 = mesh.AddEdge(vC, vD);

            FaceBase fa = mesh.AddFace(e1, e2, e3);
            FaceBase fb = mesh.AddFace(e1, e5, e4);
            FaceBase fc = mesh.AddFace(e2, e6, e5);
            FaceBase fd = mesh.AddFace(e3, e4, e6);

            Assert.AreNotEqual(e1, e2);
            Assert.AreNotEqual(e2, e3);
            Assert.AreNotEqual(e3, e4);
            Assert.AreNotEqual(e4, e5);
            Assert.AreNotEqual(e5, e6);

            Assert.AreEqual(3, vA.Degree);
            Assert.AreEqual(3, vB.Degree);
            Assert.AreEqual(3, vC.Degree);
            Assert.AreEqual(3, vD.Degree);

            Assert.AreEqual(4, mesh.VertexCount);
            Assert.AreEqual(6, mesh.EdgeCount);

            Assert.AreEqual(3, fa.EdgeCount);
            Assert.AreEqual(3, fb.EdgeCount);
            Assert.AreEqual(3, fc.EdgeCount);
            Assert.AreEqual(3, fd.EdgeCount);
        }
コード例 #13
0
ファイル: MeshTests.cs プロジェクト: vcer007/geodyssey
        public void Triangle()
        {
            VertexBase vA = new VertexBase();
            VertexBase vB = new VertexBase();
            VertexBase vC = new VertexBase();

            mesh.Add(vA);
            mesh.Add(vB);
            mesh.Add(vC);

            EdgeBase eA = mesh.AddEdge(vB, vC);
            EdgeBase eB = mesh.AddEdge(vC, vA);
            EdgeBase eC = mesh.AddEdge(vA, vB);

            Assert.AreNotSame(eA, eB);
            Assert.AreNotSame(eB, eC);
            Assert.AreNotSame(eC, eA);
            Assert.AreEqual(2, vA.Degree);
            Assert.AreEqual(2, vB.Degree);
            Assert.AreEqual(2, vC.Degree);
        }
コード例 #14
0
        private static bool NextNeighbour(Grapher <VertexBase> graph, HashSet <VertexBase> discoveredVertices, VertexBase source, VertexBase target)
        {
            if (IsVertexDiscovered(discoveredVertices, target))
            {
                return(true);
            }

            DiscoverVertex(discoveredVertices, target);

            foreach (var v in graph.Neighbours(target))
            {
                if (v.Name == source.Name)
                {
                    continue;
                }

                if (NextNeighbour(graph, discoveredVertices, target, v))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #15
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public bool IsBetween(VertexBase <T> a, VertexBase <T> b)
 {
     return(a == From && b == To || a == To && b == From);
 }
コード例 #16
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public DataEdge(VertexBase <T> from, VertexBase <T> to, TData data) : base(from, to)
 {
     Data = data;
 }
コード例 #17
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public DirectedEdge(VertexBase <T> from, VertexBase <T> to) : base(from, to)
 {
 }
コード例 #18
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public DirectedDataEdge(VertexBase <T> from, VertexBase <T> to, TData data) : base(from, to, data)
 {
 }
コード例 #19
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public override VertexBase <T> Other(VertexBase <T> vertexOld)
 {
     return(vertexOld == From ? To : null);
 }
コード例 #20
0
 private static bool IsVertexDiscovered(HashSet <VertexBase> discoveredVertices, VertexBase v)
 {
     return(discoveredVertices.Contains(v));
 }
コード例 #21
0
 private static void DiscoverVertex(HashSet <VertexBase> discoveredVertices, VertexBase v)
 {
     discoveredVertices.Add(v);
 }
コード例 #22
0
        public static List <VertexBase> FindShortestPath(Grapher <VertexBase> graph, VertexBase startVertex, VertexBase endVertex)
        {
            Grapher <DijkstraVertex> G = ConvertToDijkstraGraph(graph);
            DijkstraVertex           s = G.VertexForName(startVertex.Name);
            DijkstraVertex           n = G.VertexForName(endVertex.Name);

            // Active set
            var A = new List <DijkstraVertex>();

            // Non-active set
            var N = new List <DijkstraVertex>();

            var predecessorList = new Dictionary <DijkstraVertex, DijkstraVertex>();
            var lastVertex      = s;

            foreach (var p in G.Vertices)
            {
                predecessorList.Add(p, null);
            }

            // Init
            s.Distance = 0;
            A.AddRange(G.Vertices);

            A = A.OrderBy(x => x.Distance).ToList();

            if (s.Name == n.Name)
            {
                Debug.WriteLine("Start and endnote is equal, returning!");
                return(new List <VertexBase>());
            }

            //var handleMap = A.AddRange(G.Vertices);
            for (int i = 0; i < A.Count;)
            {
                var v = A.ElementAt(i);

                if (v.Distance != double.PositiveInfinity)
                {
                    double min = A[0].Distance;

                    for (int j = 0; j < A.Count; j++)
                    {
                        if (A.ElementAt(j).Distance == min)
                        {
                            N.Add(A.ElementAt(j));
                            i++;
                        }
                    }

                    foreach (var d in N) // N needs to be cleared after each iteration
                    {
                        Debug.WriteLine("Node finished: " + d.Name + ", Distance:" + d.Distance);
                        A.Remove(d);
                        i--;
                    }

                    foreach (var e in G.Edges)
                    {
                        if (N.Contains(e.V1) && A.Contains(e.V0))
                        {
                            var d = e.V1.Distance + e.Weight;
                            if (d < e.V0.Distance)
                            {
                                e.V0.Distance         = d;
                                predecessorList[e.V0] = e.V1; //Add actual predecessor to e.v0
                            }
                            Debug.WriteLine("New Distance for " + e.V0.Name + ": " + e.V0.Distance);
                        }
                        else if (N.Contains(e.V0) && A.Contains(e.V1))
                        {
                            var d = e.V0.Distance + e.Weight;
                            if (d < e.V1.Distance)
                            {
                                e.V1.Distance         = d;
                                predecessorList[e.V1] = e.V0; //Add actual predecessor to e.v0
                            }
                            Debug.WriteLine("New Distance for " + e.V1.Name + ": " + e.V1.Distance);
                        }
                    }
                    A = A.OrderBy(x => x.Distance).ToList();
                    N.Clear();
                }
            }

            List <VertexBase> shortestPath = new List <VertexBase>();
            var actualPredecessor          = predecessorList[n];

            if (predecessorList[n].Name == s.Name) // Path only has EndVertex and StartVertex -> finished!
            {
                shortestPath.Add(n);
                shortestPath.Add(s);

                return(shortestPath);
            }
            else
            {
                shortestPath.Add(n);

                // Find shortest path to endVertex
                while (actualPredecessor.Name != s.Name)
                {
                    if (predecessorList[actualPredecessor].Name == s.Name) // Predecessor of actual predecessor is s -> finished!
                    {
                        shortestPath.Add(actualPredecessor);
                        shortestPath.Add(s);

                        return(shortestPath);
                    }
                    else
                    {
                        shortestPath.Add(actualPredecessor);
                    }

                    actualPredecessor = predecessorList[actualPredecessor];
                }
            }

            return(null);
        }
コード例 #23
0
ファイル: Edge.cs プロジェクト: oparkerj/AdventOfCode
 public Edge(VertexBase <T> from, VertexBase <T> to)
 {
     From = from;
     To   = to;
 }