protected void DrawAxes(Graphics g, Matrix3d ProjMatrix)
        {
            GraphicsState     _s1 = g.Save();
            GraphicsContainer a   = g.BeginContainer();

            g.Transform = m1;
            double[] _p1 = ProjMatrix.ApplyTransform(m_x.X, m_x.Y, m_x.Z, 1);
            double[] _p2 = ProjMatrix.ApplyTransform(m_y.X, m_y.Y, m_y.Z, 1);
            double[] _p3 = ProjMatrix.ApplyTransform(m_z.X, m_z.Y, m_z.Z, 1);
            double[] _p0 = ProjMatrix.ApplyTransform(m_origin.X, m_origin.Y, m_origin.Z, 1);

            m_projOrigin.X = (int)_p0[0]; m_projOrigin.Y = -(int)_p0[1];
            m_projX.X      = (int)_p1[0]; m_projX.Y = -(int)_p1[1];
            m_projY.X      = (int)_p2[0]; m_projY.Y = -(int)_p2[1];
            m_projZ.X      = (int)_p3[0]; m_projZ.Y = -(int)_p3[1];

            g.DrawLine(m_xColor, m_projOrigin, m_projX);
            g.DrawLine(m_yColor, m_projOrigin, m_projY);
            g.DrawLine(m_zColor, m_projOrigin, m_projZ);
            g.DrawString("X", m_font, m_brush, m_projX);
            g.DrawString("Y", m_font, m_brush, m_projY);
            g.DrawString("Z", m_font, m_brush, m_projZ);
            g.ResetTransform();
            g.EndContainer(a);
            g.Restore(_s1);
        }
        public void Project(double theta = 0, double phi = 0, double tx = 0, double ty = 0, double tz = 0)
        {
            if (m_upVector == Vector3d.YAxis)
            {
                m_temp.Y = Distance * Math.Sin(Math.PI * (m_cameraPhi + phi) / 180);
                m_temp.X = Distance * Math.Cos(Math.PI * (m_cameraTheta + theta) / 180) * Math.Cos(Math.PI * (m_cameraPhi + phi) / 180);
                m_temp.Z = Distance * Math.Sin(Math.PI * (m_cameraTheta + theta) / 180) * Math.Cos(Math.PI * (m_cameraPhi + phi) / 180);
            }
            else
            {
                m_temp.Z = Distance * Math.Sin(Math.PI * (m_cameraPhi + phi) / 180);
                m_temp.X = Distance * Math.Cos(Math.PI * (m_cameraTheta + theta) / 180) * Math.Cos(Math.PI * (m_cameraPhi + phi) / 180);
                m_temp.Y = Distance * Math.Sin(Math.PI * (m_cameraTheta + theta) / 180) * Math.Cos(Math.PI * (m_cameraPhi + phi) / 180);
            }

            double _sin1, _cos1, _sin2, _cos2, _sin3, _cos3;
            double _d1, _d2, _d3;

            Matrix3d _m1 = Matrix3d.IdentityMatrix();

            _m1.Translate(-(m_temp.X), -(m_temp.Y), -(m_temp.Z));

            Point3d _dist = m_temp - TargetPoint;

            _d2 = m_temp.DistanceTo(TargetPoint);
            _d1 = Math.Sqrt((_dist.X * _dist.X) + (_dist.Z * _dist.Z));

            // X Axis rotation
            Matrix3d _m2 = Matrix3d.IdentityMatrix();

            if (_d1 != 0.0)
            {
                _sin1            = -_dist.X / _d1;
                _cos1            = _dist.Z / _d1;
                _m2.Matrix[0, 0] = _cos1;
                _m2.Matrix[0, 2] = -_sin1;
                _m2.Matrix[2, 0] = _sin1;
                _m2.Matrix[2, 2] = _cos1;
            }
            // Y Axis rotation
            _d2 = Math.Sqrt((_dist.X * _dist.X) + (_dist.Y * _dist.Y) + (_dist.Z * _dist.Z));
            Matrix3d _m3 = Matrix3d.IdentityMatrix();

            if (_d2 != 0.0)
            {
                _sin2            = _dist.Y / _d2;
                _cos2            = _d1 / _d2;
                _m3.Matrix[1, 1] = _cos2;
                _m3.Matrix[1, 2] = _sin2;
                _m3.Matrix[2, 1] = -_sin2;
                _m3.Matrix[2, 2] = _cos2;
            }
            double[] _up2 = _m2.ApplyTransform(m_upVector.X, UpVector.Y, UpVector.Z, 1);
            double[] _up1 = _m3.ApplyTransform(_up2[0], _up2[1], _up2[2], _up2[3]);

            // Z Axis Rotation
            _d3 = Math.Sqrt((_up1[0] * _up1[0]) + (_up1[1] * _up1[1]));
            Matrix3d _m4 = Matrix3d.IdentityMatrix();

            if (_d3 != 0.0)
            {
                _sin3            = _up1[0] / _d3;
                _cos3            = _up1[1] / _d3;
                _m4.Matrix[0, 0] = _cos3;
                _m4.Matrix[0, 1] = _sin3;
                _m4.Matrix[1, 0] = -_sin3;
                _m4.Matrix[1, 1] = _cos3;
            }
            Matrix3d _m5 = Matrix3d.IdentityMatrix();

            if (ProjectType == ProjectionTypes.Perspective && _d2 != 0.0)
            {
                _m5.Matrix[2, 3] = -1 / _d2;
            }
            else
            {
                _m5 = Matrix3d.IdentityMatrix();
            }
            Matrix3d _a   = Matrix3d.MatrixMultiply3D(_m1, _m2);
            Matrix3d _b   = Matrix3d.MatrixMultiply3D(_m3, _m4);
            Matrix3d _res = Matrix3d.MatrixMultiply3D(_a, _b);

            // Still in progress code
            if (m_viewType == ViewTypes.Front)
            {
                Matrix3d m_view = Matrix3d.IdentityMatrix();

                m_view.Matrix[2, 2] = 0;

                ProjectedMatrix = m_view;
            }
            else if (m_viewType == ViewTypes.Top)
            {
                Matrix3d m_view = Matrix3d.IdentityMatrix();
                m_view.Matrix[1, 1] = 0;
                m_view.Matrix[2, 1] = -1;
                m_view.Matrix[2, 2] = 0;
                ProjectedMatrix     = m_view;
            }
            else if (m_viewType == ViewTypes.Left)
            {
                Matrix3d m_view = Matrix3d.IdentityMatrix();
                m_view.Matrix[0, 0] = 0;
                m_view.Matrix[2, 0] = -1;
                m_view.Matrix[2, 2] = 0;
                ProjectedMatrix     = m_view;
            }
            else
            {
                ProjectedMatrix = Matrix3d.MatrixMultiply3D(_res, _m5);
            }
        }