// Scale
        public override Matrix44Adaptor SetScaling(double allScale, PointAdaptor basePoint)
        {
            Debug.Assert(allScale > 0 && basePoint != null);
            if (!(allScale > 0 && basePoint != null)) return this;

            PointAdaptor origin = new NativePointAdaptor(0,0,0);
            if (basePoint.IsEqualTo(origin))
            {
                SetScaling(allScale);
            }
            else
            {
                // Transform the origin to the base point.
                NativeMatrix44Adaptor T = NativeMatrix44Adaptor.Identity;
                T.SetTranslation(origin - basePoint);

                // zoom
                NativeMatrix44Adaptor S = NativeMatrix44Adaptor.Identity;
                S.SetScaling(allScale);

                // Recover the coordinate of the base point
                NativeMatrix44Adaptor T_1 = T.Inverse as NativeMatrix44Adaptor;

                NativeMatrix44Adaptor R = (T_1 * S * T) as NativeMatrix44Adaptor;
                m_Matrix2d = new NativeMatrix2dAdaptor(R.m_Matrix2d);
            }

            return this;
        }
        // Rotate the angle is radian
        public override Matrix44Adaptor SetRotate(double AngleThita, UnitVectorAdaptor axis, PointAdaptor basePoint)
        {
            Debug.Assert(axis != null && basePoint != null);
            if (!(axis != null && basePoint != null)) return this;

            UnitizeSubmatrixA();

            // Translation the origin to base point
            NativeMatrix44Adaptor TA = NativeMatrix44Adaptor.Identity;

            NativePointAdaptor origin = new NativePointAdaptor(0, 0, 0);
            TA.SetTranslation(origin - basePoint);

            // Rotate the axis by X'-axis to X'-Z' plane
            double CosAlpha = 0;
            double SinAlpha = 0;
            double v = System.Math.Sqrt(axis.Y * axis.Y
                 + axis.Z * axis.Z);
            if (MathUtil.IsTwoDoubleEqual(v, 0))
            {
                // The axis is parallel to X-axis
                CosAlpha = 1;
                SinAlpha = 0;
            }
            else
            {
                CosAlpha = axis.Z / v;
                SinAlpha = axis.Y / v;
            }

            NativeMatrix44Adaptor Rx = NativeMatrix44Adaptor.Identity;
            Rx[1, 1] = CosAlpha;
            Rx[1, 2] = -SinAlpha;
            Rx[2, 1] = SinAlpha;
            Rx[2, 2] = CosAlpha;

            // Rotate the axis by Y'-axis to Z'-axis
            double u = axis.Length();

            double CosBeta = v / u;
            double SinBeta = -axis.X / u;

            NativeMatrix44Adaptor Ry = NativeMatrix44Adaptor.Identity;
            Ry[0, 0] = CosBeta;
            Ry[0, 2] = SinBeta;
            Ry[2, 0] = -SinBeta;
            Ry[2, 2] = CosBeta;

            // Rotate by Z'
            double CosThita = System.Math.Cos(AngleThita);
            double SinThita = System.Math.Sin(AngleThita);
            NativeMatrix44Adaptor Rz = NativeMatrix44Adaptor.Identity;
            Rz[0, 0] = CosThita;
            Rz[0, 1] = -SinThita;
            Rz[1, 0] = SinThita;
            Rz[1, 1] = CosThita;

            // Get the inverse matrix of the above step
            NativeMatrix44Adaptor Ry_1 = Ry.Inverse as NativeMatrix44Adaptor;
            NativeMatrix44Adaptor Rx_1 = Rx.Inverse as NativeMatrix44Adaptor;
            NativeMatrix44Adaptor TA_1 = TA.Inverse as NativeMatrix44Adaptor;

            // The transform result
            Matrix44Adaptor R = TA_1 * Rx_1 * Ry_1 * Rz * Ry * Rx * TA;

            // Save the result
            for (int row = 0; row < 3; row++)
                for (int column = 0; column < 3; column++)
                    m_Matrix2d[row, column] = R[row, column];

            return this;
        }