protected virtual void ComputeWcs()
        {
            if (header.ContainsKey("CROTA2"))
            {
                rotation    = double.Parse(header["CROTA2"].Trim());
                hasRotation = true;
            }

            if (header.ContainsKey("CDELT1"))
            {
                scaleX = double.Parse(header["CDELT1"].Trim());

                if (header.ContainsKey("CDELT2"))
                {
                    scaleY   = double.Parse(header["CDELT2"].Trim());
                    hasScale = true;
                }
            }

            if (header.ContainsKey("CRPIX1"))
            {
                referenceX = double.Parse(header["CRPIX1"].Trim()) - 1;

                if (header.ContainsKey("CRPIX2"))
                {
                    referenceY = double.Parse(header["CRPIX2"].Trim()) - 1;
                    hasPixel   = true;
                }
            }
            bool galactic = false;
            bool tan      = false;

            if (header.ContainsKey("CTYPE1"))
            {
                if (header["CTYPE1"].IndexOf("GLON-") > -1)
                {
                    galactic = true;
                    tan      = true;
                }
                if (header["CTYPE2"].IndexOf("GLAT-") > -1)
                {
                    galactic = true;
                    tan      = true;
                }

                if (header["CTYPE1"].IndexOf("-TAN") > -1)
                {
                    tan = true;
                }
                if (header["CTYPE1"].IndexOf("-SIN") > -1)
                {
                    tan = true;
                }
            }

            if (!tan)
            {
                throw new System.Exception("Only TAN projected images are supported: ");
            }

            hasSize = true;

            if (header.ContainsKey("CRVAL1"))
            {
                centerX = Double.Parse(header["CRVAL1"].Trim());

                if (header.ContainsKey("CRVAL2"))
                {
                    centerY     = double.Parse(header["CRVAL2"].Trim());
                    hasLocation = true;
                }
            }

            if (galactic)
            {
                double[] result = Coordinates.GalactictoJ2000(centerX, centerY);
                centerX = result[0];
                centerY = result[1];
            }

            if (header.ContainsKey("CD1_1") && header.ContainsKey("CD1_2") &&
                header.ContainsKey("CD2_1") && header.ContainsKey("CD2_2"))
            {
                cd1_1 = double.Parse(header["CD1_1"].Trim());
                cd1_2 = double.Parse(header["CD1_2"].Trim());
                cd2_1 = double.Parse(header["CD2_1"].Trim());
                cd2_2 = double.Parse(header["CD2_2"].Trim());
                if (!hasRotation)
                {
                    CalculateRotationFromCD();
                }
                if (!hasScale)
                {
                    CalculateScaleFromCD();
                }
                hasScale    = true;
                hasRotation = true;
            }


            ValidWcs = hasScale && hasRotation && hasPixel && hasLocation;
        }
        public void SetupMatricesSpace3d(double canvasWidth, double canvasHeight)
        {
            Lighting = false;
            if (!firstTimeInit)
            {
                galacticMatrix = Matrix3d.Identity;
                // -28.9361739586894, 17.7603329867975
                galacticMatrix.Multiply(Matrix3d.RotationY(-(270 - (17.7603329867975 * 15)) / 180.0 * Math.PI));
                galacticMatrix.Multiply(Matrix3d.RotationX(-((-28.9361739586894)) / 180.0 * Math.PI));
                galacticMatrix.Multiply(Matrix3d.RotationZ(((31.422052860102041270114993238783) - 90) / 180.0 * Math.PI));
                //galacticMatrix.Transpose();
                //galacticMatrix.Invert();
                firstTimeInit = true;
            }


            Space = true;
            RenderTriangle.CullInside = true;

            Matrix3d WorldMatrix = Matrix3d.Identity;

            if (Settings.Active.GalacticMode)
            {
                WorldMatrix.Multiply(galacticMatrix);
                WorldMatrix.Multiply(Matrix3d.RotationY(((az)) / 180.0 * Math.PI));
                WorldMatrix.Multiply(Matrix3d.RotationX(-((alt)) / 180.0 * Math.PI));
                double[] gPoint = Coordinates.GalactictoJ2000(az, alt);

                viewPoint        = Coordinates.RADecTo3dAu(gPoint[0] / 15, gPoint[1], 1.0);
                TargetCamera.Lng = this.RAtoViewLng(gPoint[0] / 15);
                TargetCamera.Lat = gPoint[1];
                ViewCamera.Lat   = TargetCamera.Lat;
                ViewCamera.Lng   = TargetCamera.Lng;
            }
            else
            {
                WorldMatrix.Multiply(Matrix3d.RotationY(-((ViewCamera.Lng - 90)) / 180.0 * Math.PI));
                WorldMatrix.Multiply(Matrix3d.RotationX(-((ViewCamera.Lat)) / 180.0 * Math.PI));
                viewPoint = Coordinates.RADecTo3dAu(RA, Dec, 1.0);
            }



            double camLocal = ((ViewCamera.Rotation /*+ 90*/));

            fovAngle = ((this.ViewCamera.Zoom) / FOVMULT) / Math.PI * 180;
            fovScale = (fovAngle / canvasHeight) * 3600;

            //Settings.Global.LocalHorizonMode = true;

            // altaz
            if (Settings.Active.LocalHorizonMode && backgroundImageset.DataSetType == ImageSetType.Sky)
            {
                Coordinates zenithAltAz = new Coordinates(0, 0);

                zenithAltAz.Az = 0;

                zenithAltAz.Alt = 0;

                Coordinates zenith = Coordinates.HorizonToEquitorial(zenithAltAz, SpaceTimeController.Location, SpaceTimeController.Now);
                //Coordinates zenith2 = Coordinates.HorizonToEquitorial(zenithAltAz, Coordinates.FromLatLng(1, 1), SpaceTimeController.Now);
                //Coordinates zenith3 = Coordinates.HorizonToEquitorial(zenithAltAz, Coordinates.FromLatLng(-1, 1), SpaceTimeController.Now);

                double raPart  = -((zenith.RA - 6) / 24.0 * (Math.PI * 2));
                double decPart = -(((zenith.Dec)) / 360.0 * (Math.PI * 2));
                string raText  = Coordinates.FormatDMS(zenith.RA);
                WorldMatrix = Matrix3d.RotationY(-raPart - Math.PI);
                WorldMatrix.Multiply(Matrix3d.RotationX(decPart));

                if (SpaceTimeController.Location.Lat < 0)
                {
                    WorldMatrix.Multiply(Matrix3d.RotationY(((az) / 180.0 * Math.PI)));

                    WorldMatrix.Multiply(Matrix3d.RotationX(((alt) / 180.0 * Math.PI)));
                    camLocal += Math.PI;
                }
                else
                {
                    WorldMatrix.Multiply(Matrix3d.RotationY(((-az) / 180.0 * Math.PI)));

                    WorldMatrix.Multiply(Matrix3d.RotationX(((-alt) / 180.0 * Math.PI)));
                }

                Coordinates currentRaDec = Coordinates.HorizonToEquitorial(Coordinates.FromLatLng(alt, az), SpaceTimeController.Location, SpaceTimeController.Now);

                ViewCamera.Lat = TargetCamera.Lat = currentRaDec.Dec;
                ViewCamera.Lng = TargetCamera.Lng = RAtoViewLng(currentRaDec.RA);
            }
            World     = WorldMatrix;
            WorldBase = WorldMatrix.Clone();
            // altaz



            double localZoomFactor = ViewCamera.Zoom;

            double FovAngle = ((localZoomFactor) / FOVMULT) / Math.PI * 180;

            CameraPosition = Vector3d.Create(0.0, 0.0, 0.0);
            // This is for distance Calculation. For space everything is the same distance, so camera target is key.

            View     = Matrix3d.LookAtLH(CameraPosition, Vector3d.Create(0.0, 0.0, -1.0), Vector3d.Create(Math.Sin(camLocal), Math.Cos(camLocal), 0.0));
            ViewBase = View.Clone();

            double m_nearPlane = .1;

            nearPlane  = .1f;
            Projection = Matrix3d.PerspectiveFovLH((localZoomFactor) / FOVMULT, (double)canvasWidth / (double)canvasHeight, .1, -2.0);


            SetMatrixes();

            MakeFrustum();
        }