ApplyToQuaternion() public method

Applies a Mobius transformation to a quaternion with a zero k component (handled as a vector). The complex Mobius coefficients are treated as quaternions with zero j,k values. This is also infinity safe.
public ApplyToQuaternion ( Vector3D q ) : Vector3D
q Vector3D
return Vector3D
Ejemplo n.º 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 );
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Helper to apply a Mobius to the ball model.
 /// Vector is taken to UHS, mobius applied, then taken back.
 /// </summary>
 public static Vector3D ApplyMobius( Mobius m, Vector3D v )
 {
     v = BallToUHS( v );
     v = m.ApplyToQuaternion( v );
     return UHSToBall( v );
 }
Ejemplo n.º 3
0
        /// <summary>
        /// A helper for adding a sphere.  center should be passed in the ball model.
        /// The approach is similar to how we do the bananas below.
        /// </summary>
        public static void AddSphere( Shapeways mesh, Vector3D center, H3.Settings settings )
        {
            Vector3D centerUHS = H3Models.BallToUHS( center );

            // Find the Mobius we need.
            // We'll do this in two steps.
            // (1) Find a mobius taking center to (0,0,h).
            // (2) Deal with scaling to a height of 1.
            Vector3D flattened = centerUHS;
            flattened.Z = 0;
            Mobius m1 = new Mobius( flattened, Complex.One, Infinity.InfinityVector );
            Vector3D centerUHS_transformed = m1.ApplyToQuaternion( centerUHS );
            double scale = 1.0 / centerUHS_transformed.Z;
            Mobius m2 = new Mobius( scale, Complex.Zero, Complex.Zero, Complex.One );
            Mobius m = m2 * m1;	// Compose them (multiply in reverse order).

            // Add the sphere at the Ball origin.
            // It will *always* be generated with the same radius.
            Shapeways tempMesh = new Shapeways();
            tempMesh.AddSphere( new Vector3D(), H3Models.Ball.SizeFunc( new Vector3D(), settings.AngularThickness ) );

            // Unwind the transforms.
            for( int i=0; i<tempMesh.Mesh.Triangles.Count; i++ )
            {
                tempMesh.Mesh.Triangles[i] = new Mesh.Triangle(
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].a ),
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].b ),
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].c ) );
            }

            Banana.TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }
Ejemplo n.º 4
0
        internal static void TakePointsBack( Mesh mesh, Mobius m, H3.Settings settings )
        {
            for( int i=0; i<mesh.Triangles.Count; i++ )
            {
                mesh.Triangles[i] = new Mesh.Triangle(
                    m.ApplyToQuaternion( mesh.Triangles[i].a ),
                    m.ApplyToQuaternion( mesh.Triangles[i].b ),
                    m.ApplyToQuaternion( mesh.Triangles[i].c ) );

                /*if( Infinity.IsInfinite( mesh.Triangles[i].a ) ||
                    Infinity.IsInfinite( mesh.Triangles[i].b ) ||
                    Infinity.IsInfinite( mesh.Triangles[i].c ) )
                    System.Diagnostics.Debugger.Break();*/
            }

            // Take all points back to Ball, if needed.
            if( !settings.Halfspace )
            {
                for( int i=0; i<mesh.Triangles.Count; i++ )
                {
                    mesh.Triangles[i] = new Mesh.Triangle(
                        H3Models.UHSToBall( mesh.Triangles[i].a ),
                        H3Models.UHSToBall( mesh.Triangles[i].b ),
                        H3Models.UHSToBall( mesh.Triangles[i].c ) );
                }
            }
        }