Пример #1
0
        /// <summary>
        /// Make an edge mesh of a regular tiling.
        /// </summary>
        public static Mesh MakeEdgeMesh( int p, int q )
        {
            Mesh mesh = new Mesh();

            int maxTiles = 400;

            Tiling tiling = new Tiling();
            TilingConfig config = new TilingConfig( p, q, maxTiles: maxTiles );
            config.Shrink = 0.6;
            tiling.GenerateInternal( config );

            TilingConfig boundaryConfig = new TilingConfig( 14, 7, maxTiles: 1 );
            boundaryConfig.Shrink = 1.01;
            Tile boundary = Tiling.CreateBaseTile( boundaryConfig );

            AddSymmetryTriangles( mesh, tiling, boundary.Drawn );
            //AddSymmetryTriangles( mesh, tiling, null );
            return mesh;

            HashSet<Vector3D> completed = new HashSet<Vector3D>();
            int count = 0;
            foreach( Tile tile in tiling.Tiles )
            {
                MeshEdges( mesh, tile, completed, null );
                count++;
                if( count >= maxTiles )
                    break;
            }

            return mesh;
        }
Пример #2
0
        private static void HopfFibration(Tiling tiling)
        {
            int       segDivisions = 10;
            Shapeways mesh         = new Shapeways();

            HashSet <Vector3D> done = new HashSet <Vector3D>();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    if (done.Contains(seg.Midpoint))
                    {
                        continue;
                    }

                    // Subdivide the segment, and project points to S2.
                    Vector3D[] points = seg.Subdivide(segDivisions).Select(v => Spherical2D.PlaneToSphere(v)).ToArray();
                    foreach (Vector3D point in points)
                    {
                        Vector3D[] circlePoints = OneHopfCircle(point);
                        ProjectAndAddS3Points(mesh, circlePoints, shrink: false);
                    }

                    done.Add(seg.Midpoint);
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, @"D:\p4\R3\sample\out1.stl");
        }
Пример #3
0
        public Tile[] FundamentalCell()
        {
            Tile template = TemplateTile();

            Tile.ShrinkTile(ref template, 0.9);

            // Generate a cell tiling.
            TilingConfig tilingConfig = new TilingConfig(Q, P);
            Tiling       poly         = new Tiling();

            poly.Generate(tilingConfig);
            m_tiles = poly.Tiles.ToList();
            //SetupTransformCircle( tile );	// Call this before transforming.
            //SetupNeighborCircle( tile );

            // Generate our cell.
            List <Tile> cellTiles = new List <Tile>();

            foreach (Tile t in poly.Tiles)
            {
                Tile temp = template.Clone();
                temp.Transform(t.Isometry.Inverse());
                cellTiles.Add(temp);
            }

            return(cellTiles.ToArray());
        }
Пример #4
0
        private static void GetAssociatedTiling(int p, int q, int maxTiles, out Tiling tiling)
        {
            TilingConfig tilingConfig = new TilingConfig(p, q, maxTiles: maxTiles);

            tiling = new Tiling();
            tiling.GenerateInternal(tilingConfig, p == 6 ? Polytope.Projection.VertexCentered : Polytope.Projection.FaceCentered);
        }
Пример #5
0
        private static void HopfFibration(Tiling tiling)
        {
            int       segDivisions    = 10;
            int       circleDivisions = 125;
            Shapeways mesh            = new Shapeways();

            HashSet <Vector3D> done = new HashSet <Vector3D>();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    if (done.Contains(seg.Midpoint))
                    {
                        continue;
                    }

                    // Subdivide the segment, and project points to S2.
                    Vector3D[] points = seg.Subdivide(segDivisions).Select(v => Spherical2D.PlaneToSphere(v)).ToArray();
                    foreach (Vector3D point in points)
                    {
                        // Get the hopf circle and add to mesh.
                        // http://en.wikipedia.org/wiki/Hopf_fibration#Explicit_formulae
                        double a      = point.X;
                        double b      = point.Y;
                        double c      = point.Z;
                        double factor = 1 / (Math.Sqrt(1 + c));
                        if (Tolerance.Equal(c, -1))
                        {
                            continue;
                        }

                        List <Vector3D> circlePoints = new List <Vector3D>();
                        double          angleInc     = 2 * Math.PI / circleDivisions;
                        double          angle        = 0;
                        for (int i = 0; i <= circleDivisions; i++)
                        {
                            double sinTheta = Math.Sin(angle);
                            double cosTheta = Math.Cos(angle);
                            circlePoints.Add(new Vector3D(
                                                 (1 + c) * cosTheta,
                                                 a * sinTheta - b * cosTheta,
                                                 a * cosTheta + b * sinTheta,
                                                 (1 + c) * sinTheta));

                            angle += angleInc;
                        }

                        bool shrink = false;
                        ProjectAndAddS3Points(mesh, circlePoints.ToArray(), shrink);
                    }

                    done.Add(seg.Midpoint);
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, @"D:\p4\R3\sample\out1.stl");
        }
Пример #6
0
        private static Segment[] BaseTileSegments(int p, int q)
        {
            Tiling       tiling   = new Tiling();
            TilingConfig config   = new TilingConfig(p, q, 1);
            Tile         baseTile = Tiling.CreateBaseTile(config);

            //baseTile.Transform( Mobius.Scale( 2 ) );				// Only works in Euclidean case
            return(baseTile.Boundary.Segments.ToArray());
        }
Пример #7
0
        private static void GetAssociatedTiling(EHoneycomb honeycomb, out Tiling tiling, out Tile baseTile)
        {
            int p, q;

            GetPQ(honeycomb, out p, out q);
            TilingConfig tilingConfig = new TilingConfig(p, q, maxTiles: m_params.MaxTiles);

            tiling = new Tiling();
            tiling.Generate(tilingConfig);

            baseTile = Tiling.CreateBaseTile(tilingConfig);
        }
Пример #8
0
        public static void Cell633()
        {
            TilingConfig config = new TilingConfig( 6, 3, maxTiles: 20000 );
            Tiling tiling = new Tiling();
            tiling.GenerateInternal( config, Polytope.Projection.VertexCentered );

            double edgeLength = Honeycomb.EdgeLength( 6, 3, 3 );

            double z = 0.25;
            double offset = H3Models.UHS.ToEHorizontal( edgeLength, z );
            double scale = offset / tiling.Tiles.First().Boundary.Segments.First().Length;
            foreach( Tile tile in tiling.Tiles )
                tile.Transform( Mobius.Scale( scale ) );

            Vector3D dummy;
            double radius;
            H3Models.UHS.Geodesic( new Vector3D( 0, 0, z ), new Vector3D( scale, 0, z ), out dummy, out radius );
            Vector3D midradius = H3Models.UHSToBall( new Vector3D( 0, 0, radius ) );
            double temp = midradius.Z;
            double temp2 = ( 1 - temp ) / 2;
            double temp3 = temp + temp2;
            double temp4 = temp3;

            Vector3D circumradius = H3Models.UHSToBall( new Vector3D( 0, 0, z ) );
            temp = circumradius.Z;
            temp2 = ( 1 - temp ) / 2;
            temp3 = temp + temp2;
            temp4 = temp3;

            // Checking
            /*
            Vector3D test = new Vector3D( offset, 0, z );
            test = H3Models.UHSToBall( test );
            double edgeLength2 = DonHatch.e2hNorm( test.Abs() );
            edgeLength2 += 0;
            */

            HashSet<H3.Cell.Edge> edges = new HashSet<H3.Cell.Edge>();
            foreach( Tile tile in tiling.Tiles )
                foreach( Segment seg in tile.Boundary.Segments )
                {
                    H3.Cell.Edge edge = new H3.Cell.Edge(
                        H3Models.UHSToBall( seg.P1 + new Vector3D( 0, 0, z ) ),
                        H3Models.UHSToBall( seg.P2 + new Vector3D( 0, 0, z ) ) );
                    edges.Add( edge );
                }

            PovRay.WriteH3Edges( new PovRay.Parameters(), edges.ToArray(), "edges.pov" );
        }
Пример #9
0
        /// <summary>
        /// A static helper to generate two dual tilings.
        /// </summary>
        /// <remarks>{p,q} will have a vertex at the center.</remarks>
        /// <remarks>{q,p} will have its center at the center.</remarks>
        public static void MakeDualTilings(out Tiling tiling1, out Tiling tiling2, int p, int q)
        {
            tiling1 = new Tiling();
            tiling2 = new Tiling();

            int          maxTiles = 2000;
            TilingConfig config1  = new TilingConfig(p, q, maxTiles);
            TilingConfig config2  = new TilingConfig(q, p, maxTiles);

            tiling1.GenerateInternal(config1, Polytope.Projection.FaceCentered);
            tiling2.GenerateInternal(config2, Polytope.Projection.VertexCentered);

            /*
             * Circle c = new Circle();
             * c.Radius = .9;
             * tiling1.Clip( c );
             * tiling2.Clip( c );
             */
        }
Пример #10
0
        /// <summary>
        /// Make an edge mesh of a regular tiling.
        /// </summary>
        public static Mesh MakeEdgeMesh(int p, int q)
        {
            Mesh mesh = new Mesh();

            int maxTiles = 400;

            Tiling       tiling = new Tiling();
            TilingConfig config = new TilingConfig(p, q, maxTiles: maxTiles);

            config.Shrink = 0.6;
            tiling.GenerateInternal(config);

            TilingConfig boundaryConfig = new TilingConfig(14, 7, maxTiles: 1);

            boundaryConfig.Shrink = 1.01;
            Tile boundary = Tiling.CreateBaseTile(boundaryConfig);

            AddSymmetryTriangles(mesh, tiling, boundary.Drawn);
            //AddSymmetryTriangles( mesh, tiling, null );
            return(mesh);
        }
Пример #11
0
        /// <summary>
        /// Make an edge mesh of a regular tiling.
        /// </summary>
        public static Mesh MakeEdgeMesh(int p, int q)
        {
            Mesh mesh = new Mesh();

            int maxTiles = 400;

            Tiling       tiling = new Tiling();
            TilingConfig config = new TilingConfig(p, q, maxTiles: maxTiles);

            config.Shrink = 0.6;
            tiling.GenerateInternal(config);

            TilingConfig boundaryConfig = new TilingConfig(14, 7, maxTiles: 1);

            boundaryConfig.Shrink = 1.01;
            Tile boundary = Tiling.CreateBaseTile(boundaryConfig);

            AddSymmetryTriangles(mesh, tiling, boundary.Drawn);
            //AddSymmetryTriangles( mesh, tiling, null );
            return(mesh);

            HashSet <Vector3D> completed = new HashSet <Vector3D>();
            int count = 0;

            foreach (Tile tile in tiling.Tiles)
            {
                MeshEdges(mesh, tile, completed, null);
                count++;
                if (count >= maxTiles)
                {
                    break;
                }
            }

            return(mesh);
        }
Пример #12
0
        public static void Polarity()
        {
            TilingConfig config = new TilingConfig( 3, 7, 50 );
            Tiling tiling = new Tiling();
            tiling.GenerateInternal( config );

            List<Vector3D> points = new List<Vector3D>();
            List<H3.Cell.Edge> edges = new List<H3.Cell.Edge>();

            foreach( Polygon p in tiling.Tiles.Select( t => t.Boundary ) )
            foreach( Segment s in p.Segments )
            foreach( Vector3D v in s.Subdivide( 25 ) )
            {
                Vector3D klein = HyperbolicModels.PoincareToKlein( v );
                H3.Cell.Edge e = Dual( klein );
                points.Add( klein );
                edges.Add( e );
            }

            using( StreamWriter sw = File.CreateText( "polarity.pov" ) )
            {
                double rad = 0.01;
                foreach( Vector3D vert in points )
                    sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = rad } ) );
                foreach( H3.Cell.Edge edge in edges )
                    sw.WriteLine( PovRay.Cylinder( edge.Start, edge.End, rad/2 ) );
            }
        }
Пример #13
0
        private static List<H3.Cell.Edge> CopyAndProject( List<H3.Cell.Edge> regionEdges, Tiling tiling, double scale, Vector3D offset )
        {
            HashSet<H3.Cell.Edge> newEdges = new HashSet<H3.Cell.Edge>( new H3.Cell.EdgeEqualityComparer() );
            //foreach( Tile tile in tiling.Tiles )	// Needed for doing full ball (rather than just half of it)
            Tile tile = tiling.Tiles.First();
            {
                foreach( H3.Cell.Edge edge in regionEdges )
                {
                    // Translation
                    // The isometry is necessary for the 363, but seems to mess up 636
                    Vector3D start = tile.Isometry.Apply( edge.Start ) + offset;
                    Vector3D end = tile.Isometry.Apply( edge.End ) + offset;
                    //Vector3D start = edge.Start + tile.Center + offset;
                    //Vector3D end = edge.End + tile.Center + offset;

                    // Scaling
                    start *= scale;
                    end *= scale;

                    // Projections
                    start = H3Models.UHSToBall( start );
                    end = H3Models.UHSToBall( end );

                    H3.Cell.Edge transformed = new H3.Cell.Edge( start, end );
                    if( EdgeOkBall( transformed ) )
                        newEdges.Add( transformed );
                }
            }

            return newEdges.ToList();
        }
Пример #14
0
 private static Segment[] BaseTileSegments( int p, int q )
 {
     Tiling tiling = new Tiling();
     TilingConfig config = new TilingConfig( p, q, 1 );
     Tile baseTile = Tiling.CreateBaseTile( config );
     //baseTile.Transform( Mobius.Scale( 2 ) );				// Only works in Euclidean case
     return baseTile.Boundary.Segments.ToArray();
 }
Пример #15
0
        private static void GetAssociatedTiling( EHoneycomb honeycomb, out Tiling tiling, out Tile baseTile )
        {
            int p, q;
            GetPQ( honeycomb, out p, out q );
            TilingConfig tilingConfig = new TilingConfig( p, q, maxTiles: m_params.MaxTiles );
            tiling = new Tiling();
            tiling.Generate( tilingConfig );

            baseTile = Tiling.CreateBaseTile( tilingConfig );
        }
Пример #16
0
        /// <summary>
        /// Helper to do one step of reflections.
        /// Returns a new list of region edges.
        /// </summary>
        private static List<H3.Cell.Edge> DoOneStep( List<H3.Cell.Edge> regionEdges, Tiling tiling, Circle region )
        {
            HashSet<H3.Cell.Edge> newEdges = new HashSet<H3.Cell.Edge>( new H3.Cell.EdgeEqualityComparer() );
            foreach( Tile tile in tiling.Tiles )
            {
                foreach( H3.Cell.Edge edge in regionEdges )
                {
                    H3.Cell.Edge toAdd = null;
                    if( !Tolerance.Zero( tile.Center.Abs() ) )
                    {
                        // Translate
                        // The isometry is necessary for the 363, but seems to mess up 636
                        Vector3D start = tile.Isometry.Apply( edge.Start );
                        Vector3D end = tile.Isometry.Apply( edge.End );
                        //Vector3D start = edge.Start + tile.Center;
                        //Vector3D end = edge.End + tile.Center;

                        // Reflect
                        start = region.ReflectPoint( start );
                        end = region.ReflectPoint( end );

                        toAdd = new H3.Cell.Edge( start, end );
                    }
                    else
                        toAdd = edge;

                    if( EdgeOkUHS( toAdd, region ) )
                        newEdges.Add( toAdd );
                }
            }

            return newEdges.ToList();
        }
Пример #17
0
        private static void AddSymmetryTriangles(Mesh mesh, Tiling tiling, Polygon boundary)
        {
            // Assume template centered at the origin.
            Polygon         template     = tiling.Tiles.First().Boundary;
            List <Triangle> templateTris = new List <Triangle>();

            foreach (Segment seg in template.Segments)
            {
                int num = 1 + (int)(seg.Length * m_divisions);

                Vector3D a        = new Vector3D();
                Vector3D b        = seg.P1;
                Vector3D c        = seg.Midpoint;
                Vector3D centroid = (a + b + c) / 3;

                Polygon poly = new Polygon();
                Segment segA = Segment.Line(new Vector3D(), seg.P1);
                Segment segB = seg.Clone();
                segB.P2 = seg.Midpoint;
                Segment segC = Segment.Line(seg.Midpoint, new Vector3D());
                poly.Segments.Add(segA);
                poly.Segments.Add(segB);
                poly.Segments.Add(segC);

                Vector3D[] coords   = TextureHelper.TextureCoords(poly, Geometry.Hyperbolic);
                int[]      elements = TextureHelper.TextureElements(3, LOD: 3);
                for (int i = 0; i < elements.Length / 3; i++)
                {
                    int      idx1 = i * 3;
                    int      idx2 = i * 3 + 1;
                    int      idx3 = i * 3 + 2;
                    Vector3D v1   = coords[elements[idx1]];
                    Vector3D v2   = coords[elements[idx2]];
                    Vector3D v3   = coords[elements[idx3]];
                    templateTris.Add(new Triangle(v1, v2, v3));
                }

                /*
                 *
                 * // Need to shrink a little, so we won't
                 * // get intersections among neighboring faces.
                 * a = Shrink( a, centroid );
                 * b = Shrink( b, centroid );
                 * c = Shrink( c, centroid );
                 *
                 * Vector3D[] list = seg.Subdivide( num * 2 );
                 * list[0] = b;
                 * list[list.Length / 2] = c;
                 * for( int i = 0; i < list.Length / 2; i++ )
                 *      templateTris.Add( new Triangle( centroid, list[i], list[i + 1] ) );
                 *
                 * for( int i = num - 1; i >= 0; i-- )
                 *      templateTris.Add( new Triangle( centroid, a + (c - a) * (i + 1) / num, a + (c - a) * i / num ) );
                 *
                 * for( int i = 0; i < num; i++ )
                 *      templateTris.Add( new Triangle( centroid, a + (b - a) * i / num, a + (b - a) * (i + 1) / num ) );
                 */
            }

            foreach (Tile tile in tiling.Tiles)
            {
                Vector3D a = tile.Boundary.Segments[0].P1;
                Vector3D b = tile.Boundary.Segments[1].P1;
                Vector3D c = tile.Boundary.Segments[2].P1;

                Mobius m = new Mobius();
                if (tile.Isometry.Reflected)
                {
                    m.MapPoints(template.Segments[0].P1, template.Segments[1].P1, template.Segments[2].P1, c, b, a);
                }
                else
                {
                    m.MapPoints(template.Segments[0].P1, template.Segments[1].P1, template.Segments[2].P1, a, b, c);
                }

                foreach (Triangle tri in templateTris)
                {
                    Triangle transformed = new Triangle(
                        m.Apply(tri.a),
                        m.Apply(tri.b),
                        m.Apply(tri.c));
                    CheckAndAdd(mesh, transformed, boundary);
                }
            }
        }
Пример #18
0
        /// <summary>
        /// A static helper to generate two dual tilings.
        /// </summary>
        /// <remarks>{p,q} will have a vertex at the center.</remarks>
        /// <remarks>{q,p} will have its center at the center.</remarks>
        public static void MakeDualTilings( out Tiling tiling1, out Tiling tiling2, int p, int q )
        {
            tiling1 = new Tiling();
            tiling2 = new Tiling();

            int maxTiles = 2000;
            TilingConfig config1 = new TilingConfig( p, q, maxTiles );
            TilingConfig config2 = new TilingConfig( q, p, maxTiles );
            tiling1.GenerateInternal( config1, Polytope.Projection.FaceCentered );
            tiling2.GenerateInternal( config2, Polytope.Projection.VertexCentered );

            /*
            Circle c = new Circle();
            c.Radius = .9;
            tiling1.Clip( c );
            tiling2.Clip( c );
            */
        }
Пример #19
0
        private static void AddSymmetryTriangles( Mesh mesh, Tiling tiling, Polygon boundary )
        {
            // Assume template centered at the origin.
            Polygon template = tiling.Tiles.First().Boundary;
            List<Triangle> templateTris = new List<Triangle>();
            foreach( Segment seg in template.Segments )
            {
                int num = 1 + (int)(seg.Length * m_divisions);

                Vector3D a = new Vector3D();
                Vector3D b = seg.P1;
                Vector3D c = seg.Midpoint;
                Vector3D centroid = ( a + b + c ) / 3;

                Polygon poly = new Polygon();
                Segment segA = Segment.Line( new Vector3D(), seg.P1 );
                Segment segB = seg.Clone();
                segB.P2 = seg.Midpoint;
                Segment segC = Segment.Line( seg.Midpoint, new Vector3D() );
                poly.Segments.Add( segA );
                poly.Segments.Add( segB );
                poly.Segments.Add( segC );

                Vector3D[] coords = TextureHelper.TextureCoords( poly, Geometry.Hyperbolic );
                int[] elements = TextureHelper.TextureElements( 3, LOD: 3 );
                for( int i = 0; i < elements.Length / 3; i++ )
                {
                    int idx1 = i * 3;
                    int idx2 = i * 3 + 1;
                    int idx3 = i * 3 + 2;
                    Vector3D v1 = coords[elements[idx1]];
                    Vector3D v2 = coords[elements[idx2]];
                    Vector3D v3 = coords[elements[idx3]];
                    templateTris.Add( new Triangle( v1, v2, v3 ) );
                }

                /*

                // Need to shrink a little, so we won't
                // get intersections among neighboring faces.
                a = Shrink( a, centroid );
                b = Shrink( b, centroid );
                c = Shrink( c, centroid );

                Vector3D[] list = seg.Subdivide( num * 2 );
                list[0] = b;
                list[list.Length / 2] = c;
                for( int i = 0; i < list.Length / 2; i++ )
                    templateTris.Add( new Triangle( centroid, list[i], list[i + 1] ) );

                for( int i = num - 1; i >= 0; i-- )
                    templateTris.Add( new Triangle( centroid, a + (c - a) * (i + 1) / num, a + (c - a) * i / num ) );

                for( int i = 0; i < num; i++ )
                    templateTris.Add( new Triangle( centroid, a + (b - a) * i / num, a + (b - a) * (i + 1) / num ) );
                */
            }

            foreach( Tile tile in tiling.Tiles )
            {
                Vector3D a = tile.Boundary.Segments[0].P1;
                Vector3D b = tile.Boundary.Segments[1].P1;
                Vector3D c = tile.Boundary.Segments[2].P1;

                Mobius m = new Mobius();
                if( tile.Isometry.Reflected )
                    m.MapPoints( template.Segments[0].P1, template.Segments[1].P1, template.Segments[2].P1, c, b, a );
                else
                    m.MapPoints( template.Segments[0].P1, template.Segments[1].P1, template.Segments[2].P1, a, b, c );

                foreach( Triangle tri in templateTris )
                {
                    Triangle transformed = new Triangle(
                        m.Apply( tri.a ),
                        m.Apply( tri.b ),
                        m.Apply( tri.c ) );
                    CheckAndAdd( mesh, transformed, boundary );
                }
            }
        }
Пример #20
0
        /// <summary>
        /// Helper to do one step of reflections.
        /// Returns a new list of region edges.
        /// </summary>
        private static List <H3.Cell.Edge> DoOneStep(List <H3.Cell.Edge> regionEdges, Tiling tiling, Circle region)
        {
            HashSet <H3.Cell.Edge> newEdges = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (H3.Cell.Edge edge in regionEdges)
                {
                    H3.Cell.Edge toAdd = null;
                    if (!Tolerance.Zero(tile.Center.Abs()))
                    {
                        // Translate
                        // The isometry is necessary for the 363, but seems to mess up 636
                        Vector3D start = tile.Isometry.Apply(edge.Start);
                        Vector3D end   = tile.Isometry.Apply(edge.End);
                        //Vector3D start = edge.Start + tile.Center;
                        //Vector3D end = edge.End + tile.Center;

                        // Reflect
                        start = region.ReflectPoint(start);
                        end   = region.ReflectPoint(end);

                        toAdd = new H3.Cell.Edge(start, end);
                    }
                    else
                    {
                        toAdd = edge;
                    }

                    if (EdgeOkUHS(toAdd, region))
                    {
                        newEdges.Add(toAdd);
                    }
                }
            }

            return(newEdges.ToList());
        }
Пример #21
0
        private static Sphere[] SphericalCellFacetMirrors( HoneycombDef imageData )
        {
            int p = imageData.P;
            int q = imageData.Q;
            int r = imageData.R;

            double inRadius = Honeycomb.InRadius( p, q, r );
            //inRadius *= 1.4;	// Experimenting with {3,3,u}

            Tiling tiling = new Tiling();
            TilingConfig config = new TilingConfig( p, q );
            tiling.GenerateInternal( config, imageData.Projection );

            Sphere[] mirrors = H3.GenFacetSpheres( tiling, inRadius )
                .Select( f => f.Sphere ).ToArray();

            return mirrors;
        }
Пример #22
0
        private static List <H3.Cell.Edge> CopyAndProject(List <H3.Cell.Edge> regionEdges, Tiling tiling, double scale, Vector3D offset)
        {
            HashSet <H3.Cell.Edge> newEdges = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());
            //foreach( Tile tile in tiling.Tiles )	// Needed for doing full ball (rather than just half of it)
            Tile tile = tiling.Tiles.First();

            {
                foreach (H3.Cell.Edge edge in regionEdges)
                {
                    // Translation
                    // The isometry is necessary for the 363, but seems to mess up 636
                    Vector3D start = tile.Isometry.Apply(edge.Start) + offset;
                    Vector3D end   = tile.Isometry.Apply(edge.End) + offset;
                    //Vector3D start = edge.Start + tile.Center + offset;
                    //Vector3D end = edge.End + tile.Center + offset;

                    // Scaling
                    start *= scale;
                    end   *= scale;

                    // Projections
                    start = H3Models.UHSToBall(start);
                    end   = H3Models.UHSToBall(end);

                    H3.Cell.Edge transformed = new H3.Cell.Edge(start, end);
                    if (EdgeOkBall(transformed))
                    {
                        newEdges.Add(transformed);
                    }
                }
            }

            return(newEdges.ToList());
        }
Пример #23
0
        public static void Generate(EHoneycomb honeycomb, H3.Settings settings)
        {
            // XXX - Block the same as in H3.  Share code better.
            H3.Cell template = null;
            {
                int p, q, r;
                Honeycomb.PQR(honeycomb, out p, out q, out r);

                // Get data we need to generate the honeycomb.
                Polytope.Projection projection = Polytope.Projection.FaceCentered;
                double phi, chi, psi;
                H3.HoneycombData(honeycomb, out phi, out chi, out psi);

                H3.SetupCentering(honeycomb, settings, phi, chi, psi, ref projection);

                Tiling       tiling = new Tiling();
                TilingConfig config = new TilingConfig(p, q);
                tiling.GenerateInternal(config, projection);

                H3.Cell first = new H3.Cell(p, H3.GenFacets(tiling));
                first.ToSphere();                       // Work in ball model.
                first.ScaleToCircumSphere(1.0);
                first.ApplyMobius(settings.Mobius);

                template = first;
            }

            // Center
            Vector3D center = template.Center;

            // Face
            H3.Cell.Facet facet = template.Facets[0];
            Sphere        s     = H3Models.Ball.OrthogonalSphereInterior(facet.Verts[0], facet.Verts[1], facet.Verts[2]);
            Vector3D      face  = s.Center;

            face.Normalize();
            face *= DistOriginToOrthogonalSphere(s.Radius);

            // Edge
            Circle3D c;

            H3Models.Ball.OrthogonalCircleInterior(facet.Verts[0], facet.Verts[1], out c);
            Vector3D edge = c.Center;

            edge.Normalize();
            edge *= DistOriginToOrthogonalSphere(c.Radius);

            // Vertex
            Vector3D vertex = facet.Verts[0];

            Tet fundamental = new Tet(center, face, edge, vertex);

            // Recurse.
            int level = 1;
            Dictionary <Tet, int> completedTets = new Dictionary <Tet, int>(new TetEqualityComparer());

            completedTets.Add(fundamental, level);
            List <Tet> tets = new List <Tet>();

            tets.Add(fundamental);
            ReflectRecursive(level, tets, completedTets, settings);

            Shapeways mesh = new Shapeways();

            foreach (KeyValuePair <Tet, int> kvp in completedTets)
            {
                if (Utils.Odd(kvp.Value))
                {
                    continue;
                }

                Tet tet = kvp.Key;

                // XXX - really want sphere surfaces here.
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[1], tet.Verts[2]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[3], tet.Verts[1]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[2], tet.Verts[3]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[1], tet.Verts[3], tet.Verts[2]));
            }

            mesh.Mesh.Scale(settings.Scale);
            STL.SaveMeshToSTL(mesh.Mesh, H3.m_baseDir + "fundamental" + ".stl");
        }
Пример #24
0
        private static void HopfFibration( Tiling tiling )
        {
            int segDivisions = 10;
            Shapeways mesh = new Shapeways();

            HashSet<Vector3D> done = new HashSet<Vector3D>();
            foreach( Tile tile in tiling.Tiles )
            foreach( Segment seg in tile.Boundary.Segments )
            {
                if( done.Contains( seg.Midpoint ) )
                    continue;

                // Subdivide the segment, and project points to S2.
                Vector3D[] points = seg.Subdivide( segDivisions ).Select( v => Spherical2D.PlaneToSphere( v ) ).ToArray();
                foreach( Vector3D point in points )
                {
                    Vector3D[] circlePoints = OneHopfCircle( point );
                    ProjectAndAddS3Points( mesh, circlePoints, shrink: false );
                }

                done.Add( seg.Midpoint );
            }

            STL.SaveMeshToSTL( mesh.Mesh, @"D:\p4\R3\sample\out1.stl" );
        }
Пример #25
0
        // https://plus.google.com/u/0/117663015413546257905/posts/BnCEkdNiTZ2
        public static void TwinDodecs()
        {
            Tiling tiling = new Tiling();
            TilingConfig config = new TilingConfig( 5, 3 );
            tiling.GenerateInternal( config, Polytope.Projection.VertexCentered );	// Vertex-centered makes infinities tricky

            Dodec dodec = new Dodec();
            foreach( Tile tile in tiling.Tiles )
            foreach( Segment seg in tile.Boundary.Segments )
            {
                Vector3D p1 = seg.P1, p2 = seg.P2;
                if( Infinity.IsInfinite( p1 ) )
                    p1 = Infinity.InfinityVector;
                if( Infinity.IsInfinite( p2 ) )
                    p2 = Infinity.InfinityVector;

                dodec.Verts.Add( p1 );
                dodec.Verts.Add( p2 );
                dodec.Midpoints.Add( Halfway( p1, p2 ) );
            }

            // Now recursively add more vertices.
            HashSet<Vector3D> allVerts = new HashSet<Vector3D>();
            foreach( Vector3D v in dodec.Verts )
                allVerts.Add( v );
            RecurseTwins( allVerts, dodec, 0 );

            using( StreamWriter sw = File.CreateText( "dual_dodecs_points_sphere.pov" ) )
            {
                foreach( Vector3D vert in allVerts )
                {
                    Vector3D onSphere = Sterographic.PlaneToSphereSafe( vert );
                    sw.WriteLine( PovRay.Sphere( new Sphere() { Center = onSphere, Radius = 0.01 } ) );

                    //if( !Infinity.IsInfinite( vert ) )
                    //	sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) );
                }
            }
        }