Exemplo n.º 1
0
        private void OneChain()
        {
            // Here are all unattached edges.
            var edgeKvps = m_edgeMap.Where(kvp => kvp.Value.Count == 1).ToArray();

            Edge[] edges = edgeKvps.Select(kvp => kvp.Key).ToArray();

            Trace.WriteLine(string.Format("Chain length {0}", edges.Length));

            // Find all the vertices connected to two polygons.
            // This will necessarily lie on the edges above.
            // These are vertices that are candidates for filling in with a polygon.
            Vector3D[]         vertices  = m_vertexMap.Where(kvp => kvp.Value.Count > 1).Select(kvp => kvp.Key).ToArray();
            HashSet <Vector3D> edgeVerts = new HashSet <Vector3D>();

            foreach (Edge e in edges)
            {
                edgeVerts.Add(e.Start);
                edgeVerts.Add(e.End);
            }
            //Vector3D[] vertices = edgeVerts.ToArray();

            // XXX - Things that are hard.
            //	- How can we tell when a vertex is done?
            //  - How to avoid duplicating edges and vertices?

            // Attempt to fill those verts.
            foreach (Vector3D v in vertices)
            {
                Edge[] connectedEdges = m_vertexToEdgeMap[v].Intersect(edges, new H3.Cell.EdgeEqualityComparer()).ToArray();

                // Is it on the chain?
                if (connectedEdges.Length != 2)
                {
                    continue;
                }

                Edge     e1     = connectedEdges[0];
                Edge     e2     = connectedEdges[1];
                Vector3D v1     = e1.Opp(v) - v;
                Vector3D v2     = e2.Opp(v) - v;
                double   angle  = v1.AngleTo(v2);
                int      nSides = PolyWithAngle(angle);
                if (nSides != 0)
                {
                    Vector3D normal = v1.Cross(v2);
                    Polygon  poly   = Polygon.CreateEuclidean(nSides, v, e1.Opp(v), normal);

                    // Things may have changed, so we must double check.
                    if (m_edgeMap[e1].Count == 1 &&
                        m_edgeMap[e2].Count == 1)
                    {
                        AddPoly(poly);
                        Trace.WriteLine(string.Format("Added {0}-gon", nSides));
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Connects two polygons by rotating them about edges of a static polygon
        /// The three polygons will meet at a single vertex afterward (this vertex will be convex).
        /// </summary>
        private static void ConnectPolys(Polygon staticPoly, Polygon poly1, Polygon poly2)
        {
            // All three polygons should share one vertex.
            // The edges connected to this vertex (that are in the static polyhedron)
            // will be the hinges we rotate around to connect poly1 and poly2.
            // These are also the edges the static poly shares with the other two.

            Vector3D[] iVerts = staticPoly.Vertices.Intersect(poly1.Vertices).Intersect(poly2.Vertices).ToArray();
            if (iVerts.Length != 1)
            {
                throw new System.ArgumentException();
            }
            Vector3D vertex = iVerts.First();

            // Get our hinges and the two edges we want to merge.
            Edge hinge1 = Hinge(staticPoly, poly1);
            Edge hinge2 = Hinge(staticPoly, poly2);
            Edge e1     = AdjacentEdge(poly1, hinge1, vertex);
            Edge e2     = AdjacentEdge(poly2, hinge2, vertex);

            // Construct circles through the edges they will rotate through when hinged.
            Circle3D c1 = ConstructRotationCircle(hinge1, vertex, e1.Opp(vertex));
            Circle3D c2 = ConstructRotationCircle(hinge2, vertex, e2.Opp(vertex));

            // These circles both lie on the same sphere (with center = vertex and radius 1),
            // and will intersect in two points. Those two points will determine the two
            // locations we can hinge our polys to.
            Vector3D i1, i2;

            SphericalTrig.IntersectionSmart(vertex, c1, c2, out i1, out i2);

            // XXX - Need to think more about how to choose among options.
            double a1 = (e1.Opp(vertex) - c1.Center).AngleTo(i1 - c1.Center);
            double a2 = (e2.Opp(vertex) - c2.Center).AngleTo(i1 - c2.Center);

            RotatePoly(poly1, EdgeAxis(hinge1), -a1);
            RotatePoly(poly2, EdgeAxis(hinge2), a2);
        }