Ejemplo n.º 1
0
        /// <summary>
        /// Hopf Link between two points on S^2.
        /// </summary>
        public static void HopfLink(StreamWriter sw, Vector3D s2_1, Vector3D s2_2, bool anti)
        {
            Vector3D[] circlePoints;
            string     circleString;

            circlePoints = OneHopfCircleProjected(s2_1, anti);
            circleString = PovRay.EdgeSphereSweep(circlePoints, SizeFunc);
            sw.WriteLine(circleString);
            circlePoints = OneHopfCircleProjected(s2_2, anti);
            circleString = PovRay.EdgeSphereSweep(circlePoints, SizeFunc);
            sw.WriteLine(circleString);

            Mesh mesh = new Mesh();

            Vector3D[] interpolated = S3.GeodesicPoints(s2_1, s2_2);
            for (int i = 0; i < interpolated.Length - 1; i++)
            {
                Vector3D   v1 = interpolated[i];
                Vector3D   v2 = interpolated[i + 1];
                Vector3D[] p1 = OneHopfCircleProjected(v1, anti);
                Vector3D[] p2 = OneHopfCircleProjected(v2, anti);

                for (int j = 0; j < p1.Length - 1; j++)
                {
                    Mesh.Triangle t1 = new Mesh.Triangle(p1[j], p1[j + 1], p2[j]);
                    Mesh.Triangle t2 = new Mesh.Triangle(p2[j], p1[j + 1], p2[j + 1]);
                    mesh.Triangles.Add(t1);
                    mesh.Triangles.Add(t2);
                }
            }

            PovRay.WriteMesh(sw, mesh, append: true);
        }
Ejemplo n.º 2
0
 private static Mesh.Triangle Transform(Mesh.Triangle tri, System.Func <Vector3D, Vector3D> transform)
 {
     tri.a = transform(tri.a);
     tri.b = transform(tri.b);
     tri.c = transform(tri.c);
     return(tri);
 }
Ejemplo n.º 3
0
 static public void DrawTriangle(Mesh.Triangle triangle, Graphics g, ImageSpace i)
 {
     using (Pen pen = new Pen(Color.Black, 1.0f))
     {
         g.DrawLine(pen, VecToPoint(triangle.a, i), VecToPoint(triangle.b, i));
         g.DrawLine(pen, VecToPoint(triangle.b, i), VecToPoint(triangle.c, i));
         g.DrawLine(pen, VecToPoint(triangle.c, i), VecToPoint(triangle.a, i));
     }
 }
Ejemplo n.º 4
0
 private static void ReverseTris(Mesh m)
 {
     for (int i = 0; i < m.Triangles.Count; i++)
     {
         Mesh.Triangle tri = m.Triangles[i];                    // Ugh, damn you structs!
         tri.ChangeOrientation();
         m.Triangles[i] = tri;
     }
 }
Ejemplo n.º 5
0
        private static Mesh.Triangle[] ThickenSimple(Mesh.Triangle tri, Dictionary <Vector3D, Vector3D> normalMap)
        {
            List <Mesh.Triangle> result = new List <Mesh.Triangle>();

            System.Tuple <Vector3D, Vector3D> a = ThickenSimple(tri.a, normalMap);
            System.Tuple <Vector3D, Vector3D> b = ThickenSimple(tri.b, normalMap);
            System.Tuple <Vector3D, Vector3D> c = ThickenSimple(tri.c, normalMap);

            result.Add(new Mesh.Triangle(a.Item1, c.Item1, b.Item1));                   // For consistent orientations
            result.Add(new Mesh.Triangle(a.Item2, b.Item2, c.Item2));

            return(result.ToArray());
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Assumes we are in the UHS model.
        /// </summary>
        private static Mesh.Triangle[] Thicken(Mesh.Triangle tri, Sphere normal)
        {
            List <Mesh.Triangle> result = new List <Mesh.Triangle>();

            System.Tuple <Vector3D, Vector3D> a = Thicken(tri.a, normal);
            System.Tuple <Vector3D, Vector3D> b = Thicken(tri.b, normal);
            System.Tuple <Vector3D, Vector3D> c = Thicken(tri.c, normal);

            if (a == null || b == null || c == null ||
                a.Item1.DNE || a.Item2.DNE ||
                b.Item1.DNE || b.Item2.DNE ||
                c.Item1.DNE || c.Item2.DNE)
            {
                System.Console.WriteLine("bah");
            }

            result.Add(new Mesh.Triangle(a.Item1, c.Item1, b.Item1));                   // For consistent orientations
            result.Add(new Mesh.Triangle(a.Item2, b.Item2, c.Item2));

            return(result.ToArray());
        }
Ejemplo n.º 7
0
        private static void WriteTriangle(StreamWriter sw, Mesh.Triangle tri)
        {
            Vector3D v1 = tri.b - tri.a;
            Vector3D v2 = tri.c - tri.a;

            // See http://en.wikipedia.org/wiki/STL_format#The_Facet_Normal
            // about how to do the normals correctly.
            //Vector3D n = v1.Cross( v2 );
            Vector3D n = new Vector3D(0, 0, 1);

            n.Normalize();

            sw.WriteLine("  facet normal {0:e6} {1:e6} {2:e6}", n.X, n.Y, n.Z);
            sw.WriteLine("    outer loop");
            sw.WriteLine("      vertex {0:e6} {1:e6} {2:e6}", tri.a.X, tri.a.Y, tri.a.Z);
            sw.WriteLine("      vertex {0:e6} {1:e6} {2:e6}", tri.b.X, tri.b.Y, tri.b.Z);
            sw.WriteLine("      vertex {0:e6} {1:e6} {2:e6}", tri.c.X, tri.c.Y, tri.c.Z);
            sw.WriteLine("    endloop");
            sw.WriteLine("  endfacet");

            /*
             *      "  facet normal {0:e6} {1:e6} {2:e6}" -f $n
             *      "    outer loop"
             *      "      vertex {0:e6} {1:e6} {2:e6}" -f $v1
             *      "      vertex {0:e6} {1:e6} {2:e6}" -f $v2
             *      "      vertex {0:e6} {1:e6} {2:e6}" -f $v3
             *      "    endloop"
             *      "  endfacet"
             *
             * facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
             *      outer loop
             *        vertex 4.500000e-001 4.500000e-001 4.500000e-001
             *        vertex 4.500000e-001 7.500000e-001 4.500000e-001
             *        vertex 7.500000e-001 7.500000e-001 4.500000e-001
             *      endloop
             * endfacet
             */
        }
Ejemplo n.º 8
0
 private static Mesh.Triangle Transform(Mesh.Triangle tri)
 {
     return(Transform(tri, Transform));
 }
Ejemplo n.º 9
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;
                }
            }
        }
Ejemplo n.º 10
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 );
        }