AddCurve() private method

private AddCurve ( List disks, Vector3D points, Vector3D start, Vector3D end ) : void
disks List
points Vector3D
start Vector3D
end Vector3D
return void
Beispiel #1
0
        /// <summary>
        /// Add a finite (truncated) banana to our mesh.  Passed in edge should be in Ball model.
        /// </summary>
        public static void AddBanana( Shapeways mesh, Vector3D e1, Vector3D e2, H3.Settings settings )
        {
            Vector3D e1UHS = H3Models.BallToUHS( e1 );
            Vector3D e2UHS = H3Models.BallToUHS( e2 );

            // Endpoints of the goedesic on the z=0 plane.
            Vector3D z1, z2;
            H3Models.UHS.GeodesicIdealEndpoints( e1UHS, e2UHS, out z1, out z2 );

            // XXX - Do we want to do a better job worrying about rotation here?
            // (multiply by complex number with certain imaginary part as well)
            //Vector3D z3 = ( z1 + z2 ) / 2;
            //if( Infinity.IsInfinite( z3 ) )
            //	z3 = new Vector3D( 1, 0 );
            Vector3D z3 = new Vector3D( Math.E, Math.PI );	// This should vary the rotations a bunch.

            // Find the Mobius we need.
            // We'll do this in two steps.
            // (1) Find a mobius taking z1,z2 to origin,inf
            // (2) Deal with scaling e1 to a height of 1.
            Mobius m1 = new Mobius( z1, z3, z2 );
            Vector3D e1UHS_transformed = m1.ApplyToQuaternion( e1UHS );
            double scale = 1.0 / e1UHS_transformed.Z;
            Mobius m2 = Mobius.Scale( scale );
            Mobius m = m2 * m1;	// Compose them (multiply in reverse order).
            Vector3D e2UHS_transformed = m.ApplyToQuaternion( e2UHS );

            // Make our truncated cone.
            // For regular tilings, we really would only need to do this once for a given LOD.
            List<Vector3D> points = new List<Vector3D>();
            double logHeight = Math.Log( e2UHS_transformed.Z );
            if( logHeight < 0 )
                throw new System.Exception( "impl issue" );
            int div1, div2;
            H3Models.Ball.LOD_Finite( e1, e2, out div1, out div2, settings );
            double increment = logHeight / div1;
            for( int i=0; i<=div1; i++ )
            {
                double h = increment * i;

                // This is to keep different bananas from sharing exactly coincident vertices.
                double tinyOffset = 0.001;
                if( i == 0 )
                    h -= tinyOffset;
                if( i == div1 )
                    h += tinyOffset;

                Vector3D point = new Vector3D( 0, 0, Math.Exp( h ) );
                points.Add( point );
            }
            Shapeways tempMesh = new Shapeways();
            tempMesh.Div = div2;
            tempMesh.AddCurve( points.ToArray(), v => H3Models.UHS.SizeFunc( v, settings.AngularThickness ) );

            // Unwind the transforms.
            TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }
Beispiel #2
0
        /// <summary>
        /// Helper to project points from S3 -> S2, then add an associated curve.
        /// </summary>
        private static void ProjectAndAddS3Points(Shapeways mesh, Vector3D[] pointsS3, bool shrink)
        {
            // Project to S3, then to R3.
            List <Vector3D> projected = new List <Vector3D>();

            foreach (Vector3D v in pointsS3)
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe(1.0);

                // Pull R3 into a smaller open disk.
                if (shrink)
                {
                    double mag = Math.Atan(c.Abs());
                    c.Normalize();
                    c *= mag;
                }

                projected.Add(c);
            }

            System.Func <Vector3D, double> sizeFunc = v =>
            {
                // Constant thickness.
                // return 0.08;

                double sphericalThickness = 0.002;

                double abs = v.Abs();
                if (shrink)
                {
                    abs = Math.Tan(abs);                        // The unshrunk abs.
                }
                // The thickness at this vector location.
                double result = Spherical2D.s2eNorm(Spherical2D.e2sNorm(abs) + sphericalThickness) - abs;

                if (shrink)
                {
                    result *= Math.Atan(abs) / abs;                             // shrink it back down.
                }
                return(result);
            };

            mesh.AddCurve(projected.ToArray(), sizeFunc);
        }
Beispiel #3
0
        public static void GenPolyhedron()
        {
            Tiling tiling;
            int    p = 3;
            int    q = 6;

            GetAssociatedTiling(p, q, 5000, out tiling);

            double overallScale = 12.5;                 // 2.5 cm = 1 in diameter

            Shapeways mesh = new Shapeways();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    double tilingScale = 0.75;
                    seg.Scale(new Vector3D(), tilingScale);

                    Vector3D v1 = Sterographic.PlaneToSphereSafe(seg.P1);
                    Vector3D v2 = Sterographic.PlaneToSphereSafe(seg.P2);
                    //if( v1.Dist( v2 ) < 0.01 )
                    //	continue;
                    if (SphericalCoords.CartesianToSpherical(v1).Y < Math.PI / 12 &&
                        SphericalCoords.CartesianToSpherical(v2).Y < Math.PI / 12)
                    {
                        continue;
                    }

                    double dist      = v1.Dist(v2);
                    int    divisions = 2 + (int)(dist * 20);

                    Vector3D[] points = seg.Subdivide(divisions);
                    points = points.Select(v => Sterographic.PlaneToSphereSafe(v)).ToArray();
                    mesh.AddCurve(points, v => SizeFunc(v, overallScale));
                }
            }

            mesh.Mesh.Scale(overallScale);

            string outputFileName = @"d:\temp\" + p + q + ".stl";

            STL.SaveMeshToSTL(mesh.Mesh, outputFileName);
        }
Beispiel #4
0
        private static void ProjectAndAddS3Points(Shapeways mesh, Vector3D[] pointsS3)
        {
            double r = 0.02;

            List <Vector3D> projected = new List <Vector3D>();
            List <double>   radii     = new List <double>();

            foreach (Vector3D v in pointsS3)
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe(1.0);

                Vector3D p;
                double   d;
                H3Models.Ball.DupinCyclideSphere(c, r, Geometry.Spherical, out p, out d);
                projected.Add(p);
                radii.Add(d);
            }

            mesh.AddCurve(projected.ToArray(), radii.ToArray());
        }
Beispiel #5
0
        private static void AddEuclideanEdge(Shapeways mesh, HashSet <H3.Cell.Edge> completed, Vector3D start, Vector3D end)
        {
            H3.Cell.Edge edge = new H3.Cell.Edge(start, end);
            if (completed.Contains(edge))
            {
                return;
            }

            Shapeways tempMesh = new Shapeways();
            Segment   seg      = Segment.Line(start, end);

            int div = 20 - (int)(start.Abs() * 4);

            if (div < 1)
            {
                div = 1;
            }

            tempMesh.AddCurve(seg.Subdivide(div), .05);
            Transform(tempMesh.Mesh);

            mesh.Mesh.Triangles.AddRange(tempMesh.Mesh.Triangles);
            completed.Add(edge);
        }
Beispiel #6
0
        /// <summary>
        /// Helper to project points from S3 -> S2, then add an associated curve.
        /// XXX - Not completely correct.
        /// </summary>
        private static void ProjectAndAddS3Points( Shapeways mesh, Vector3D[] pointsS3, bool shrink )
        {
            List<Vector3D> projected = new List<Vector3D>();
            foreach( Vector3D v in pointsS3 )
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe( 1.0 );

                // Pull R3 into a smaller open disk.
                if( shrink )
                {
                    double mag = Math.Atan( c.Abs() );
                    c.Normalize();
                    c *= mag;
                }

                projected.Add( c );
            }

            System.Func<Vector3D, double> sizeFunc = v =>
            {
                // Constant thickness.
                // return 0.08;

                double sphericalThickness = 0.05;

                double abs = v.Abs();
                if( shrink )
                    abs = Math.Tan( abs );	// The unshrunk abs.

                // The thickness at this vector location.
                double result = Spherical2D.s2eNorm( Spherical2D.e2sNorm( abs ) + sphericalThickness ) - abs;

                if( shrink )
                    result *= Math.Atan( abs ) / abs;	// shrink it back down.

                return result;
            };

            mesh.AddCurve( projected.ToArray(), sizeFunc );
        }
Beispiel #7
0
        private static void ProjectAndAddS3Points( Shapeways mesh, Vector3D[] pointsS3 )
        {
            double r = 0.02;

            List<Vector3D> projected = new List<Vector3D>();
            List<double> radii = new List<double>();
            foreach( Vector3D v in pointsS3 )
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe( 1.0 );

                Vector3D p;
                double d;
                H3Models.Ball.DupinCyclideSphere( c, r, Geometry.Spherical, out p, out d );
                projected.Add( p );
                radii.Add( d );
            }

            mesh.AddCurve( projected.ToArray(), radii.ToArray() );
        }
Beispiel #8
0
        /// <summary>
        /// Add an ideal banana to our mesh.  Passed in edge should be in Ball model.
        /// </summary>
        public static void AddIdealBanana( Shapeways mesh, Vector3D e1, Vector3D e2, H3.Settings settings )
        {
            Vector3D z1 = H3Models.BallToUHS( e1 );
            Vector3D z2 = H3Models.BallToUHS( e2 );

            // Mobius taking z1,z2 to origin,inf
            Complex dummy = new Complex( Math.E, Math.PI );
            Mobius m = new Mobius( z1, dummy, z2 );

            // Make our truncated cone.  We need to deal with the two ideal endpoints specially.
            List<Vector3D> points = new List<Vector3D>();
            double logHeight = 2;	// XXX - magic number, and going to cause problems for infinity checks if too big.
            int div1, div2;
            H3Models.Ball.LOD_Ideal( e1, e2, out div1, out div2, settings );
            double increment = logHeight / div1;
            for( int i=-div1; i<=div1; i+=2 )
                points.Add( new Vector3D( 0, 0, Math.Exp( increment * i ) ) );

            Shapeways tempMesh = new Shapeways();
            tempMesh.Div = div2;
            System.Func<Vector3D, double> sizeFunc = v => H3Models.UHS.SizeFunc( v, settings.AngularThickness );
            //Mesh.OpenCylinder...  pass in two ideal endpoints?
            tempMesh.AddCurve( points.ToArray(), sizeFunc, new Vector3D(), Infinity.InfinityVector );

            // Unwind the transforms.
            TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }