예제 #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);
        }
예제 #2
0
        private static string Edge(Parameters parameters, Geometry g, H3.Cell.Edge edge)
        {
            Vector3D v1 = edge.Start, v2 = edge.End;

            Vector3D[] points = null;
            Func <Vector3D, Sphere> sizeFunc = v => new Sphere()
            {
                Center = v, Radius = H3Models.SizeFuncConst(v, parameters.Scale)
            };

            //double minRad = 0.0005;
            double minRad = 0.0004;

            //double minRad = 0.0017;

            // STL
            //minRad = 0.8 / 100;

            if (parameters.Halfspace)
            {
                //v1 = H3Models.BallToUHS( v1 );
                //v2 = H3Models.BallToUHS( v2 );

                points = H3Models.UHS.GeodesicPoints(v1, v2);
                if (!parameters.ThinEdges)
                {
                    sizeFunc = v =>
                    {
                        // XXX, inexact
                        return(new Sphere()
                        {
                            Center = v, Radius = Math.Max(H3Models.UHS.SizeFunc(v, parameters.AngularThickness), minRad)
                        });
                    }
                }
                ;
            }
            else
            {
                if (g == Geometry.Hyperbolic)
                {
                    points = H3Models.Ball.GeodesicPoints(v1, v2, edge.Color.Z);
                }
                else if (g == Geometry.Spherical)
                {
                    points = S3.GeodesicPoints(v1, v2);
                    //points = points.Select( p => { p.Normalize(); return p; } ).ToArray();
                }
                else
                {
                    //points = new Vector3D[] { v1, v2 };
                    List <Vector3D> interpolated = new List <Vector3D>();
                    int             count        = 20;
                    for (int i = 0; i <= count; i++)
                    {
                        interpolated.Add(v1 + (v2 - v1) * ((double)i / count));
                    }
                    points = interpolated.ToArray();
                }

                if (!parameters.ThinEdges)
                {
                    sizeFunc = v =>
                    {
                        Vector3D c;
                        double   r;
                        H3Models.Ball.DupinCyclideSphere(v, parameters.AngularThickness / 2, g, out c, out r);
                        return(new Sphere()
                        {
                            Center = c, Radius = Math.Max(r, minRad)
                        });
                    }
                }
                ;
            }

            //if( g == Geometry.Euclidean )
            //	return EdgeCylinder( points, sizeFunc );

            return(EdgeSphereSweep(points, sizeFunc, edge.Color));
        }