Exemplo n.º 1
0
        /// <summary>
        /// Calculates a mesh for an RLD surface.
        /// </summary>
        private static Mesh SurfaceInternal(out RLD_outputs outputs)
        {
            Mesh mesh = new Mesh();

            Func <double, double, double, Vector3D[]> oneCircle = (x, o, scale) =>
            {
                Vector3D normal = Normal(x, o * scale);
                Vector3D cen    = new Vector3D(0, 0, normal.Z);
                Vector3D radius = new Vector3D(normal.X, 0);
                return(Shapeways.Disk(cen, new Vector3D(0, 0, 1), radius, m_params.Res));
            };

            outputs = RLD_Sphere(m_params.K);
            double s = m_params.Scale;

            //double s = outputs.scale;

            // Add in two bands for each segment along the profile, one for +z coords, and one for -z coords.
            Vector3D[] profile = outputs.profile;
            for (int i = 0; i < profile.Length - 1; i++)
            {
                Vector3D p1 = profile[i];
                Vector3D p2 = profile[i + 1];
                mesh.AddBand(oneCircle(p1.X, p1.Y, s), oneCircle(p2.X, p2.Y, s));
                mesh.AddBand(oneCircle(p1.X, -p1.Y, s), oneCircle(p2.X, -p2.Y, s));
            }

            return(mesh);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates a mesh for a standard euclidean catenoid.
        /// This will need to be transformed to the various locations later.
        /// </summary>
        private static Mesh StandardCatenoid(double waist, double height)
        {
            Mesh mesh = new Mesh();
            int  res  = m_params.Res * 2;

            Func <double, Vector3D[]> oneCircle = z =>
            {
                double   r      = waist * Math.Cosh(z / waist);
                Vector3D cen    = new Vector3D(0, 0, z);
                Vector3D radius = new Vector3D(r, 0);
                return(Shapeways.Disk(cen, new Vector3D(0, 0, 1), radius, res));
            };

            double inc = height / (res * 2);

            for (int i = 0; i < res; i++)
            {
                double z1 = inc * i;
                double z2 = inc * (i + 1);
                mesh.AddBand(oneCircle(z1), oneCircle(z2));
                mesh.AddBand(oneCircle(-z1), oneCircle(-z2));
            }

            return(mesh);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Ball
        /// </summary>
        private static void AddEdge(Mesh mesh, Vector3D v1, Vector3D v2)
        {
            double quality = v1.Dist(v2) * 8;                   // roughly 0 to 1.
            int    div     = (int)(quality * 16);

            if (div > 16)
            {
                div = 16;
            }
            if (div < 6)
            {
                div = 6;
            }
            div = 50;

            Vector3D[]      points  = H3Models.Ball.GeodesicPoints(v1, v2, div);
            List <Vector3D> ePoints = new List <Vector3D>();
            List <double>   eRadii  = new List <double>();

            foreach (Vector3D pNE in points)
            {
                Sphere sphere = SphereFuncBall(Geometry.Hyperbolic, pNE, false);
                ePoints.Add(sphere.Center);
                eRadii.Add(sphere.Radius);
            }

            Shapeways shapeways = new Shapeways();

            shapeways.AddCurve(ePoints.ToArray(), eRadii.ToArray());
            mesh.Append(shapeways.Mesh);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create an STL file for a cell.
        /// Currently only works for cells with both hyperideal vertices and cells.
        /// </summary>
        public static void HoneycombHyperidealLegs(HoneycombDef def, int lod, Dictionary <Vector3D, H3.Cell> complete)
        {
            int p = def.P;
            int q = def.Q;
            int r = def.R;

            m_div = TextureHelper.SetLevels(lod);

            bool ball = false;

            Sphere[]       simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: ball);
            H3.Cell.Edge[] edges;
            if (ball)
            {
                edges = SimplexCalcs.SimplexEdgesBall(p, q, r);
            }
            else
            {
                edges = SimplexCalcs.SimplexEdgesUHS(p, q, r);
            }

            // Two edges of one simplex facet.
            H3.Cell.Edge e1 = edges[2];
            H3.Cell.Edge e2 = edges[3];
            Vector3D[]   points1, points2;
            if (ball)
            {
                points1 = H3Models.Ball.GeodesicPoints(e1.Start, e1.End, 2 * m_div);
                points2 = H3Models.Ball.GeodesicPoints(e2.Start, e2.End, 2 * m_div);
            }
            else
            {
                points1 = H3Models.UHS.GeodesicPoints(e1.Start, e1.End, 2 * m_div);
                points2 = H3Models.UHS.GeodesicPoints(e2.Start, e2.End, 2 * m_div);
            }

            Sphere cellSphere   = simplex[0];
            Sphere vertexSphere = simplex[3];

            // Because one vertex the facet triangle is hyperideal, it will actually look like a square.
            List <Vector3D[]> allPoints = new List <Vector3D[]>();

            for (int i = 0; i < points1.Length; i++)
            {
                Vector3D p1 = points1[i];
                Vector3D p2 = points2[i];

                Vector3D[] arcPoints;
                if (i == points1.Length - 1)
                //if( false )
                {
                    // NOTE: This arc is not generally geodesic!
                    // Or is it?
                    arcPoints = ball ?
                                H3Models.Ball.GeodesicPoints(p1, p2, m_div) :
                                H3Models.UHS.GeodesicPoints(p1, p2, m_div);

                    /*Circle3D arc = cellSphere.Intersection( vertexSphere );
                     * double angleTot = (p1 - arc.Center).AngleTo( p2 - arc.Center );
                     * arcPoints = Shapeways.CalcArcPoints( arc.Center, arc.Radius, p1, arc.Normal, -angleTot, div );*/
                }
                else
                {
                    Circle3D c        = Circle3D.FromCenterAnd2Points(cellSphere.Center, p1, p2);
                    double   angleTot = (p1 - c.Center).AngleTo(p2 - c.Center);
                    arcPoints = Shapeways.CalcArcPoints(cellSphere.Center, cellSphere.Radius, p1, c.Normal, -angleTot, m_div);
                }
                //Vector3D[] arcPoints = new Vector3D[] { p1, p2 };
                allPoints.Add(arcPoints);
            }

            // Create the triangles for the patch.
            Mesh mesh = new Mesh();

            for (int i = 0; i < allPoints.Count - 1; i++)
            {
                Vector3D[] arc1 = allPoints[i];
                Vector3D[] arc2 = allPoints[i + 1];

                for (int j = 0; j < arc1.Length - 1; j++)
                {
                    // Points of (i,j) box;
                    Vector3D p1 = arc1[j];
                    Vector3D p2 = arc2[j];
                    Vector3D p3 = arc1[j + 1];
                    Vector3D p4 = arc2[j + 1];

                    Mesh.Triangle tri1 = new Mesh.Triangle(p1, p2, p3);
                    Mesh.Triangle tri2 = new Mesh.Triangle(p2, p4, p3);

                    // We need to thicken after reflecting around, otherwise we can't apply a min thickness.

                    /*Sphere normal = cellSphere;
                     * Mesh.Triangle[] thickened1 = Thicken( tri1, normal );
                     * Mesh.Triangle[] thickened2 = Thicken( tri2, normal );
                     * mesh.Triangles.AddRange( thickened1 );
                     * mesh.Triangles.AddRange( thickened2 );*/

                    mesh.Triangles.Add(tri1);
                    mesh.Triangles.Add(tri2);
                }
            }

            // AuxPoints will be used for multiple things.
            // - The first two points are for an an that will fill the gap where there is a missing face.
            // - We'll also store the points for the 4 edges of our fundamental triangle.
            List <Vector3D> auxPoints = new List <Vector3D>();
            {
                var             edge1 = allPoints.First();
                var             edge2 = allPoints.Last();
                List <Vector3D> edge3 = new List <Vector3D>(), edge4 = new List <Vector3D>();
                for (int i = 0; i < allPoints.Count; i++)
                {
                    edge3.Add(allPoints[i][0]);
                    edge4.Add(allPoints[i][allPoints[i].Length - 1]);
                }
                edge4.Reverse();

                auxPoints.Add(e1.Start);
                auxPoints.Add(e1.End);
                auxPoints.AddRange(edge1.Reverse());
                auxPoints.AddRange(edge2);
                auxPoints.AddRange(edge3);
                auxPoints.AddRange(edge4);
            }

            Vector3D cen = HoneycombPaper.InteriorPointBall;

            /* Reorientation code.  Move this elsewhere.
             *
             * // Face centered orientation.
             * bool faceCentered = false;
             * if( faceCentered )
             *      SimplexCalcs.PrepForFacetCentering( p, q, simplex, ref cen );
             *
             * Mobius mUHS = SimplexCalcs.FCOrientMobius( p, q );
             * Mobius mBall = HoneycombPaper.FCOrientMobius( H3Models.UHSToBall( cellSphere ) );
             *
             * simplex = simplex.Select( s =>
             * {
             *      s = H3Models.UHSToBall( s );
             *      //H3Models.TransformInBall2( s, mBall );
             *      return s;
             * } ).ToArray();
             *
             *
             * {
             *      for( int i = 0; i < mesh.Triangles.Count; i++ )
             *      {
             *              Mesh.Triangle tri = mesh.Triangles[i];
             *
             *              if( faceCentered )
             *              {
             *                      tri.a = mUHS.ApplyToQuaternion( tri.a );
             *                      tri.b = mUHS.ApplyToQuaternion( tri.b );
             *                      tri.c = mUHS.ApplyToQuaternion( tri.c );
             *              }
             *
             *              tri.a = H3Models.UHSToBall( tri.a );
             *              tri.b = H3Models.UHSToBall( tri.b );
             *              tri.c = H3Models.UHSToBall( tri.c );
             *
             *              if( faceCentered )
             *              {
             *                      tri.a = H3Models.TransformHelper( tri.a, mBall );
             *                      tri.b = H3Models.TransformHelper( tri.b, mBall );
             *                      tri.c = H3Models.TransformHelper( tri.c, mBall );
             *              }
             *              mesh.Triangles[i] = tri;
             *      }
             *
             *      if( faceCentered )
             *              cen = H3Models.TransformHelper( cen, mBall );
             * }
             */

            // Now we need to reflect around this fundamental patch.
            H3.Cell[] simplices = GenCell(simplex, mesh, cen, auxPoints.ToArray(), ball);

            // Existing cells take precedence.
            foreach (H3.Cell c in simplices)
            {
                Vector3D t = c.Center;
                H3.Cell  dummy;
                if (!complete.TryGetValue(t, out dummy))
                {
                    complete[t] = c;
                }
            }
        }
Exemplo n.º 5
0
        public static void S3BiHelicoid()
        {
            double cutoff = 8.0;
            int    div    = 500;

            Matrix4D mat = Matrix4D.MatrixToRotateinCoordinatePlane(1 * Math.PI / 4, 0, 3);
            Mesh     m1  = S3Helicoid(div, mat, reciprocal: false);
            //m1.Triangles = m1.Triangles.Where( t => t.a.Abs() < cutoff && t.b.Abs() < cutoff && t.c.Abs() < cutoff ).ToList();

            Mesh m2 = S3Helicoid(div, mat, reciprocal: true);
            //m2.Triangles = m2.Triangles.Where( t => t.a.Abs() < cutoff && t.b.Abs() < cutoff && t.c.Abs() < cutoff ).ToList();

            Mesh m3 = new Mesh();

            System.Action <bool> addCore = recip =>
            {
                List <Vector3D> circlePoints = new List <Vector3D>();
                double          aOffset      = 2 * Math.PI / div;
                for (int i = 0; i <= div; i++)
                {
                    double x = Math.Sin(aOffset * i);
                    double y = Math.Cos(aOffset * i);
                    circlePoints.Add(recip ?
                                     new Vector3D(x, y) : new Vector3D(0, 0, x, y));
                }

                // partial transform to R3 here.
                circlePoints = circlePoints.Select(p =>
                {
                    p = mat.RotateVector(p);
                    p = Sterographic.S3toR3(p);
                    return(p);
                }).ToList();

                List <Vector3D> ePoints = new List <Vector3D>();
                List <double>   eRadii  = new List <double>();
                foreach (Vector3D pNE in circlePoints)
                {
                    Sphere sphere = SphereFuncBall(Geometry.Spherical, pNE, false);
                    ePoints.Add(sphere.Center);
                    eRadii.Add(sphere.Radius);
                }

                Shapeways shapeways = new Shapeways();
                shapeways.AddClosedCurve(ePoints.ToArray(), eRadii.ToArray());
                m3.Append(shapeways.Mesh);
            };
            addCore(false);
            addCore(true);
            for (int i = 0; i < m3.Triangles.Count; i++)
            {
                Mesh.Triangle t = m3.Triangles[i];
                m3.Triangles[i] = Transform(t, SphericalModels.StereoToEquidistant);
            }

            string filename = "helicoid.stl";

            File.Delete(filename);
            using (StreamWriter sw = File.AppendText(filename))
            {
                STL.AppendMeshToSTL(m1, sw);
                STL.AppendMeshToSTL(m2, sw);
                STL.AppendMeshToSTL(m3, sw);
            }

            //HelicoidHelper( thinMesh, boundaryPoints );
        }
Exemplo n.º 6
0
        public void Gen(int p, int q, int r)
        {
            Geometry g = Util.GetGeometry(p, q, r);

            if (g != Geometry.Spherical)
            {
                throw new System.Exception("Point group code only for spherical geometry.");
            }

            Simplex simplex = new Simplex();

            simplex.Facets = SimplexCalcs.Mirrors(p, q, r);
            Vector3D cen        = new Vector3D();
            Vector3D faceCenter = SimplexCalcs.FaceCenterSpherical(p, q, r);
            Vector3D edgeMid    = SimplexCalcs.EdgeMidpointSpherical(p, q, r);
            Vector3D vertex     = SimplexCalcs.VertexSpherical(p, q, r);

            List <Vector3D> startingPoles = new List <Vector3D>();

            startingPoles.Add(Sterographic.S3toR3(GreatSphere.FromSphere(simplex.Facets[0]).Pole));
            GreatSphere[] spheres = CalcSpheres(simplex.Facets, startingPoles.ToArray());

            string filename = "point_group.pov";

            using (StreamWriter sw = File.CreateText(filename))
            {
                //foreach( var greatSphere in spheres )
                //sw.WriteLine( PovRay.Sphere( greatSphere.ToSphere() ) );
            }

            /*
             * List<H3.Cell.Edge> startingEdges = new List<H3.Cell.Edge>();
             * startingEdges.Add( new H3.Cell.Edge( cen, faceCenter ) );
             * H3.Cell.Edge[] edges = Recurse.CalcEdges( simplex.Facets, startingEdges.ToArray(), new Recurse.Settings() { G = Geometry.Spherical, Threshold = 0.001 } );
             * //edges = edges.Where( e => !( Infinity.IsInfinite( e.Start ) || Infinity.IsInfinite( e.End ) ) ).ToArray();
             *
             * PovRay.WriteEdges( new PovRay.Parameters() { AngularThickness = 0.01 }, Geometry.Spherical, edges, filename, append: true );
             */

            double minRad = 0;
            double thick  = 0.005;

            System.Func <Vector3D, Sphere> sizeFunc = v =>
            {
                Vector3D c;
                double   rad;
                H3Models.Ball.DupinCyclideSphere(v, thick / 2, g, out c, out rad);
                return(new Sphere()
                {
                    Center = c, Radius = Math.Max(rad, minRad)
                });
            };

            // All geodesics
            List <Circle3D> startingCircles = new List <Circle3D>();

            startingCircles.Add(GeodesicFrom2Points(cen, edgeMid));
            Circle3D[] geodesics = CalcGeodesics(simplex.Facets, startingCircles.ToArray());

            Vector3D color = new Vector3D(0, 0, 1);

            using (StreamWriter sw = File.CreateText(filename))
            {
                Shapeways shapeways = new Shapeways();
                foreach (Circle3D geodesic in geodesics)
                {
                    Vector3D[] points;
                    if (Infinity.IsInfinite(geodesic.Radius))
                    {
                        double  cutoff = 15;
                        Segment seg    = Segment.Line(geodesic.Normal * cutoff, geodesic.Normal * -cutoff);
                        points = seg.Subdivide(42);
                    }
                    else
                    {
                        List <Vector3D> tempPoints = geodesic.Subdivide(150).ToList();
                        tempPoints.Add(tempPoints[0]);
                        tempPoints.Add(tempPoints[1]);
                        points = tempPoints.ToArray();
                    }

                    List <Vector3D> ePoints = new List <Vector3D>();
                    List <double>   eRadii  = new List <double>();
                    foreach (Vector3D pNE in points)
                    {
                        Sphere sphere = sizeFunc(pNE);
                        ePoints.Add(sphere.Center);
                        eRadii.Add(sphere.Radius);
                    }
                    shapeways.AddCurve(ePoints.ToArray(), eRadii.ToArray());

                    sw.WriteLine(PovRay.EdgeSphereSweep(points, sizeFunc, color));
                }

                STL.SaveMeshToSTL(shapeways.Mesh, "533.stl");
            }
        }