Beispiel #1
0
        /// <summary>
        /// Build a linear transformation taking three independent vectors v1, v2, v3 to vectors w1, w2, w3 respectively.
        /// </summary>
        /// <param name="v1">1st source vector</param>
        /// <param name="v2">2nd source vector</param>
        /// <param name="v3">3rd source vector</param>
        /// <param name="w1">1st target vector (i.e., Mv1 = w1)</param>
        /// <param name="w2">2nd target vector</param>
        /// <param name="w3">3rd target vector</param>
        /// <returns></returns>
        public static LinearTransform3 VectorsToVectors(Vector3D v1, Vector3D v2, Vector3D v3, Vector3D w1, Vector3D w2, Vector3D w3)
        {
            LinearTransform3 V = new LinearTransform3(v1, v2, v3);
            LinearTransform3 W = new LinearTransform3(w1, w2, w3);

            return(W * V.InverseTransform());
        }
Beispiel #2
0
        /// <summary>
        /// Compose the linear transformation T1 with the linear transformation T2 to get T1 o T2.
        /// </summary>
        /// <param name="T1">The first transformation</param>
        /// <param name="T2">The second transformation</param>
        /// <remarks> Note that when this composite is applied to a vector v, we first apply T2 to v, and then apply T1 to the result. </remarks>
        /// <returns>The composite transformation. </returns>
        public static LinearTransform3 operator *(LinearTransform3 T1, LinearTransform3 T2)
        {
            LinearTransform3 S = new LinearTransform3();

            S.mat = MatrixProduct(T1.mat, T2.mat);
            return(S);
        }
Beispiel #3
0
        /// <summary>
        /// Compute the inverse of the transformation, if it exists.
        /// </summary>
        /// <returns>The inverse transform</returns>
        public LinearTransform3 InverseTransform()
        {
            double[,] m = MatrixInverse(mat);
            LinearTransform3 T = new LinearTransform3();

            T.mat = m;
            return(T);
        }
Beispiel #4
0
        /// <summary>
        /// Copy the [c -s; s c] matrix into a pair of rows and colums of the identity matrix, where c and s are the cosine and sine of a given angle.
        /// </summary>
        /// <param name="first">The index of the first column into which to copy the matrix</param>
        /// <param name="second">The index of the first column into which to copy the matrix</param>
        /// <param name="angle">The angle to rotate, in radians</param>
        /// <returns>A rotation transformation</returns>
        private static LinearTransform3 RotMat(int first, int second, double angle)
        {
            LinearTransform3 T = new LinearTransform3();

            T.mat[first, first]   = Math.Cos(angle);
            T.mat[second, second] = T.mat[first, first];
            T.mat[second, first]  = Math.Sin(angle);
            T.mat[first, second]  = -T.mat[second, first];
            return(T);
        }
Beispiel #5
0
        /// <summary>
        /// Build the transformation (x, y, z) -> (ax, by, cz)
        /// </summary>
        /// <param name="xscale">The scale factor for y-coordinates</param>
        /// <param name="yscale">The scale factor for y-coordinates</param>
        /// <param name="zscale">The scale factor for z-coordinates</param>
        /// <returns></returns>
        public static LinearTransform3 AxisScale(double xscale, double yscale, double zscale)
        {
            LinearTransform3 T = new LinearTransform3();

            T.mat[0, 0] = xscale;
            T.mat[1, 1] = yscale;
            T.mat[2, 2] = zscale;

            return(T);
        }
        private static ProjectiveTransform3 StandardFrameToPoints(Point3D p0, Point3D p1, Point3D p2, Point3D p3, Point3D p4)
        {
            //
            ProjectiveTransform3 T = new ProjectiveTransform3();
            // idea: send p0, p1, p2, and p3 to e1, e2, e3 and e4 by an linear transformation K of R^3; see where p4 goes; call this q.
            // build projective map P sending e1, e2, e3, e4, and u= (e1+e2+e3) to e1, e2, e3, d4, and q.
            // then let L = Kinverse; K * P sends e1 to p1; e2 to p2; e3 to p3; e4 to p4, and u to q to e4.
            ProjectiveTransform3 K = new ProjectiveTransform3();

            for (int i = 0; i < 4; i++)
            {
                K.mat[3, i] = 1.0d;
            }
            K.mat[0, 0] = p0.X;
            K.mat[1, 0] = p0.Y;
            K.mat[2, 0] = p0.Z;
            K.mat[0, 1] = p1.X;
            K.mat[1, 1] = p1.Y;
            K.mat[2, 1] = p1.Z;
            K.mat[0, 2] = p2.X;
            K.mat[1, 2] = p2.Y;
            K.mat[2, 2] = p2.Z;
            K.mat[0, 3] = p3.X;
            K.mat[1, 3] = p3.Y;
            K.mat[2, 3] = p3.Z;

            ProjectiveTransform3 L = new ProjectiveTransform3();

            L.mat = LinearTransform3.MatrixInverse(K.mat);
            double[] v = new double[3];
            v[0] = p3.X;
            v[1] = p3.Y;
            v[2] = p4.Z;
            v[3] = 1.0d;

            double[] q = new double[4];
            for (int i = 0; i < 4; i++)
            {
                double tally = 0.0d;
                for (int j = 0; j < 4; j++)
                {
                    tally += L.mat[i, j] * v[j];
                }
                q[i] = tally;
            }
            double[,] p = new double[4, 4];
            for (int i = 0; i < 4; i++)
            {
                p[i, i] = q[i];
            }
            ProjectiveTransform3 S = new ProjectiveTransform3();

            S.mat = ProjectiveTransform3.MatrixProduct(p, K.mat);
            return(S);
        }
        /// <summary>
        /// Given a point p1 and linearly independent vectors v1, v2, and v3 build the unique transformation taking p1 to q1, v1 to w1,  v2 to w2, and v3 to w3.
        /// <param name="p1">The point to be moved</param>
        /// <param name="v1">The first vector</param>
        /// <param name="v2">The second vector</param>
        /// <param name="v3">The third vector</param>
        /// <param name="q1">The point to which p1 will be moved</param>
        /// <param name="w1">The vector to which v1 will be moved</param>
        /// <param name="w2">The vector to which v2 will be moved</param>
        /// <param name="w3">The vector to which v3 will be moved</param>
        /// </summary>
        public static AffineTransform3 PointAndVectorsToPointAndVectors(
            Point3D p1, Vector3D v1, Vector3D v2, Vector3D v3,
            Point3D q1, Vector3D w1, Vector3D w2, Vector3D w3)
        {
            AffineTransform3 Trans1 = AffineTransform3.Translate(p1, new Point3D(0, 0, 0));
            LinearTransform3 T      = LinearTransform3.VectorsToVectors(v1, v2, v3, w1, w2, w3);
            AffineTransform3 Trans2 = AffineTransform3.Translate(new Point3D(0, 0, 0), q1);
            AffineTransform3 S      = new AffineTransform3();

            S.mat = T.Matrix();

            return(Trans2 * S * Trans1);
        }