public static Vector2d Average3d(Vector2d left, Vector2d right)
        {
            var pntLeft = Coordinates.GeoTo3dDouble(left.Y, left.X);
            var pntRight = Coordinates.GeoTo3dDouble(right.Y, right.X);

            var pntOut = Vector3d.Add(pntLeft, pntRight);
            pntOut.Multiply(.5);
            pntOut.Normalize();

            return CartesianToSpherical2(pntOut);
        }
 public static Vector2d TanToRaDec(Coordinates center, Vector2d point)
 {
     return TanToRaDec(new Vector2d(center.RA, center.Dec), point);
 }
        private void renderWindow_MouseMove(object sender, MouseEventArgs e)
        {



            if (contrastMode)
            {
                contrast = (1 - (e.Y / (float)ClientSize.Height));
                brightness = e.X / (float)ClientSize.Width;
                return;
            }




            if (activeTouch != TouchControls.None)
            {
                if (activeTouch == TouchControls.TrackBall)
                {
                    moveVector = new PointF(touchTrackBallCenter.X - (e.X + Properties.Settings.Default.ScreenHitTestOffsetX), touchTrackBallCenter.Y - (e.Y + Properties.Settings.Default.ScreenHitTestOffsetY));
                }

                if (activeTouch == TouchControls.PanTrack)
                {
                    Vector2d panTrack = TouchToScreen(this.panTracker);


                    Vector2d mv = new Vector2d(panTrack.X - (e.X + Properties.Settings.Default.ScreenHitTestOffsetX), panTrack.Y - (e.Y + Properties.Settings.Default.ScreenHitTestOffsetY));

                    if (mv.Length > 50)
                    {
                        mv.Normalize();
                        mv.Scale(50);
                    }

                    moveVector = new PointF((float)mv.X, (float)mv.Y);


                }

                if (activeTouch == TouchControls.ZoomTrack)
                {
                    Vector2d zoomTrack = TouchToScreen(this.zoomTracker);
                    double zoomDrag = zoomTrack.X - (e.X + Properties.Settings.Default.ScreenHitTestOffsetX);
                    if (Math.Abs(zoomDrag) > 54)
                    {
                        ZoomVector = 54 * Math.Sign(zoomDrag);
                    }
                    else
                    {
                        ZoomVector = (float)zoomDrag;
                    }
                }

                if (activeTouch == TouchControls.OrbitTrack)
                {
                    Vector2d orbitTrack = TouchToScreen(this.orbitTracker);
                    double orbitDrag = orbitTrack.X - (e.X + Properties.Settings.Default.ScreenHitTestOffsetX);
                    if (Math.Abs(orbitDrag) > 70)
                    {
                        OrbitVector = 70 * Math.Sign(orbitDrag);
                    }
                    else
                    {
                        OrbitVector = (float)orbitDrag;
                    }
                }

                return;
            }


            if (uiController != null)
            {
                if (uiController.MouseMove(sender, new MouseEventArgs(e.Button, e.Clicks, e.X + Properties.Settings.Default.ScreenHitTestOffsetX, e.Y + Properties.Settings.Default.ScreenHitTestOffsetY, e.Delta)))
                {
                    return;
                }
            }

            moved = true;


            if (lastMousePosition == e.Location)
            {
                return;
            }
            else
            {
                mouseMoved = true;
                lastMouseMove = DateTime.Now;

                if (!CursorVisible && !ProjectorServer)
                {
                    Cursor.Show();
                    CursorVisible = true;
                }

            }

            if (measuringDrag)
            {
                measureEnd = GetCoordinatesForScreenPoint(e.X, e.Y);

                if (measureLines == null)
                {

                    measureLines = new SimpleLineList11();
                    measureLines.DepthBuffered = false;

                }
                measureLines.Clear();
                measureLines.AddLine(Coordinates.RADecTo3d(measureStart.RA + 12, measureStart.Dec, 1), Coordinates.RADecTo3d(measureEnd.RA + 12, measureEnd.Dec, 1));
                double angularSperation = CAAAngularSeparation.Separation(measureStart.RA, measureStart.Dec, measureEnd.RA, measureEnd.Dec);



                TourPlace pl = new TourPlace(Language.GetLocalizedText(977, "Seperation: ") + Coordinates.FormatDMS(angularSperation), measureEnd.Dec, measureEnd.RA, Classification.Star, Constellations.Containment.FindConstellationForPoint(measureEnd.RA, measureEnd.Dec), ImageSetType.Sky, -1);
                SetLabelText(pl, true);

            }
            else if (Space && Settings.Active.GalacticMode)
            {
                if (dragging)
                {
                    Tracking = false;

                    MoveView(-(e.X - this.mouseDownX), (e.Y - this.mouseDownY), true);
                    if (!Properties.Settings.Default.SmoothPan)
                    {
                        az = targetAz;
                        alt = targetAlt;
                        double[] gPoint = Coordinates.GalactictoJ2000(az, alt);
                        TargetLat = ViewLat = gPoint[1];
                        TargetLong = ViewLong = RAtoViewLng(gPoint[0] / 15);
                        NotifyMoveComplete();
                    }
                    this.mouseDownX = e.X;
                    this.mouseDownY = e.Y;
                }
                else if (spinning || angle)
                {

                    CameraRotateTarget = (CameraRotateTarget + (((double)(e.X - this.mouseDownX)) / 1000 * Math.PI));

                    CameraAngleTarget = (CameraAngleTarget + (((double)(e.Y - this.mouseDownY)) / 1000 * Math.PI));

                    if (CameraAngleTarget < TiltMin)
                    {
                        CameraAngleTarget = TiltMin;
                    }

                    if (CameraAngleTarget > 0)
                    {
                        CameraAngleTarget = 0;
                    }

                    if (!Properties.Settings.Default.SmoothPan)
                    {
                        CameraRotate = CameraRotateTarget;
                        CameraAngle = CameraAngleTarget;
                    }

                    this.mouseDownX = e.X;
                    this.mouseDownY = e.Y;
                }
                else
                {
                    mouseMoved = true;
                    lastMouseMove = DateTime.Now;
                }
            }
            else if (Space && Settings.Active.LocalHorizonMode)
            {
                if (dragging)
                {
                    if (!SolarSystemMode)
                    {
                        Tracking = false;
                    }

                    MoveView(-(e.X - this.mouseDownX), (e.Y - this.mouseDownY), true);
                    if (!Properties.Settings.Default.SmoothPan)
                    {
                        az = targetAz;
                        alt = targetAlt;
                        Coordinates currentRaDec = Coordinates.HorizonToEquitorial(Coordinates.FromLatLng(alt, az), SpaceTimeController.Location, SpaceTimeController.Now);

                        TargetLat = ViewLat = currentRaDec.Dec;
                        TargetLong = ViewLong = RAtoViewLng(currentRaDec.RA);
                        NotifyMoveComplete();
                    }
                    this.mouseDownX = e.X;
                    this.mouseDownY = e.Y;
                }
                else
                {
                    mouseMoved = true;
                    lastMouseMove = DateTime.Now;
                }
            }
            else
            {
                if (dragging)
                {
                    if (!SolarSystemMode)
                    {
                        Tracking = false;
                    }

                    MoveView(-(e.X - this.mouseDownX), (e.Y - this.mouseDownY), true);
                    if (!Properties.Settings.Default.SmoothPan)
                    {
                        ViewLat = TargetLat;
                        ViewLong = TargetLong;
                        NotifyMoveComplete();
                    }
                    this.mouseDownX = e.X;
                    this.mouseDownY = e.Y;
                }
                else if (spinning || angle)
                {

                    CameraRotateTarget = (CameraRotateTarget + (((double)(e.X - this.mouseDownX)) / 1000 * Math.PI));

                    CameraAngleTarget = (CameraAngleTarget + (((double)(e.Y - this.mouseDownY)) / 1000 * Math.PI));

                    if (CameraAngleTarget < TiltMin)
                    {
                        CameraAngleTarget = TiltMin;
                    }

                    if (CameraAngleTarget > 0)
                    {
                        CameraAngleTarget = 0;
                    }

                    if (!Properties.Settings.Default.SmoothPan)
                    {
                        CameraRotate = CameraRotateTarget;
                        CameraAngle = CameraAngleTarget;
                    }

                    this.mouseDownX = e.X;
                    this.mouseDownY = e.Y;
                }
                else
                {
                    mouseMoved = true;
                    lastMouseMove = DateTime.Now;

                }
            }

            lastMousePosition = e.Location;
        }
        public bool MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (Earth3d.MainWindow.StudyImageset == null)
            {
                mouseDown = false;
                return false;
            }
            Tile root = TileCache.GetTile(0, 0, 0, Earth3d.MainWindow.StudyImageset, null);
            if (root == null)
            {
                mouseDown = false;
                return false;
            }
            if (e.Button == MouseButtons.Right && (root is SkyImageTile))
            {
                anchored = !anchored;
                popup.SetPivotMode(anchored);
                if (anchored)
                {
                    anchoredPoint1 = Earth3d.MainWindow.GetCoordinatesForScreenPoint(e.X, e.Y);
                    TourPlace place = new TourPlace("", anchoredPoint1.Dec, anchoredPoint1.RA, Classification.Unidentified, "UMA", ImageSetType.Sky, -1);
                    Earth3d.MainWindow.SetLabelText(place, false);
                    if (root is TangentTile)
                    {
                        TangentTile tile = (TangentTile)root;
                        Vector3d vector = tile.TransformPoint(12, 12);
                        vector = Coordinates.GeoTo3dDouble(anchoredPoint1.Lat, anchoredPoint1.Lng);
                        double x;
                        double y;
                        tile.UnTransformPoint(vector, out x, out y);
                    }
                    else if (root is SkyImageTile)
                    {
                        SkyImageTile tile = (SkyImageTile)root;
                        anchorPoint1 = tile.GetImagePixel(anchoredPoint1);
                    }
                }
                mouseDown = true;
                return true;
            }
            else if (e.Button == MouseButtons.Left)
            {
                dragging = true;
                pntDown = e.Location;
                if (anchored)
                {
                    if (root is TangentTile)
                    {
                        startRotation = Earth3d.MainWindow.StudyImageset.Rotation;
                        startCenterX = Earth3d.MainWindow.StudyImageset.OffsetX;
                        startCenterY = Earth3d.MainWindow.StudyImageset.OffsetY;
                        startScale = Earth3d.MainWindow.StudyImageset.BaseTileDegrees;
                        Coordinates downPoint = Earth3d.MainWindow.GetCoordinatesForScreenPoint(e.X, e.Y);
                        startLength = anchoredPoint1.Distance(downPoint);
                        startAngle = anchoredPoint1.Angle(downPoint) / RC;
                    }
                    else if (root is SkyImageTile)
                    {
                        SkyImageTile tile = (SkyImageTile)root;
                        anchoredPoint2 = Earth3d.MainWindow.GetCoordinatesForScreenPoint(e.X, e.Y);
                        anchorPoint2 = tile.GetImagePixel(anchoredPoint2);

                    }
                }
                mouseDown = true;
                return true;
            }
            else
            {
                mouseDown = false;
                return false;
            }
        }
        public bool MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //pntDown = e.Location;

            if (dragMode != Draging.None)
            {
                double dist = 0;
                double distX = e.X - pntDown.X;
                double distY = -(e.Y - pntDown.Y);

                if (lockPreferedAxis)
                {
                    if (preferY)
                    {
                        dist = distY;
                        preferY = true;
                        Cursor.Current = Cursors.SizeNS;
                    }
                    else
                    {
                        dist = distX;
                        preferY = false;
                        Cursor.Current = Cursors.SizeWE;
                    }
                }
                else
                {
                    if (Math.Abs(distX) > Math.Abs(distY))
                    {
                        dist = distX;
                        preferY = false;
                    }
                    else
                    {
                        dist = distY;
                        preferY = true;
                    }
                    if (dist > 5)
                    {
                        lockPreferedAxis = true;
                    }
                }

                switch (dragMode)
                {
                    case Draging.None:
                        break;
                    case Draging.X:
                        this.translate.X = valueOnDown + (12 * uiScale * (dist / Earth3d.MainWindow.RenderContext11.ViewPort.Width));
                        break;
                    case Draging.Y:
                        this.translate.Y = valueOnDown + (12 * uiScale * (dist / Earth3d.MainWindow.RenderContext11.ViewPort.Width));
                        break;
                    case Draging.Z:
                        this.translate.Z = valueOnDown + (12 * uiScale * (dist / Earth3d.MainWindow.RenderContext11.ViewPort.Width));
                        break;
                    case Draging.HP:
                        this.heading = valueOnDown - distX / 4;
                        this.pitch = valueOnDown2 + distY / 4;
                        break;
                    case Draging.PR:
                        this.pitch = valueOnDown + distY / 4;
                        this.roll = valueOnDown2 - distX / 4;
                        break;
                    case Draging.RH:
                        this.roll = valueOnDown + distY / 4;
                        this.heading = valueOnDown2 - distX / 4;
                        break;
                    case Draging.HP1:
                        this.heading = valueOnDown - distX / 4;
                        this.pitch = valueOnDown2 - distY / 4;
                        break;
                    case Draging.PR1:
                        this.pitch = valueOnDown + distY / 4;
                        this.roll = valueOnDown2 + distX / 4;
                        break;
                    case Draging.RH1:
                        this.roll = valueOnDown - distY / 4;
                        this.heading = valueOnDown2 - distX / 4;
                        break;
                    case Draging.Scale:
                        this.scale.X = this.scale.Y = this.scale.Z = valueOnDown * Math.Pow(2, (dist / 100));
                        break;
                    default:
                        break;
                }
                FireChanged();
                return true;
            }
            else
            {
                Vector2d pnt = new Vector2d(e.X, e.Y);

                if ((pnt - xHandle).Length < hitDist)
                {
                    Cursor.Current = Cursors.SizeAll;
                    return true;
                }

                if ((pnt - yHandle).Length < hitDist)
                {
                    Cursor.Current = Cursors.SizeAll;
                    return true;
                }

                if ((pnt - zHandle).Length < hitDist)
                {
                    Cursor.Current = Cursors.SizeAll;
                    return true;
                }

                for (int i = 0; i < hprHandles.Length; i++)
                {
                    if ((pnt - hprHandles[i]).Length < hitDist)
                    {
                        Cursor.Current = Cursors.SizeAll;
                        return true;
                    }
                }
            }

            return false;
        }
 private Vector2d PointToTouch(Vector2d pnt)
 {
     return new Vector2d(pnt.X - (renderWindow.Width - 207), pnt.Y - (renderWindow.Height - (234 + 120)));
 }
        private WcsSolution SolveOld(CorresponencePoint a, CorresponencePoint b)
        {
            WcsSolution s = new WcsSolution();
            Vector2d center = new Vector2d(width / 2, height / 2);
            Vector2d temp = a.Image - b.Image;
            double imageLength = temp.Length;
            double angularSperation = CAAAngularSeparation.Separation(a.Celestial.RA, a.Celestial.Dec, b.Celestial.RA, b.Celestial.Dec);

            // Degrees per pixel
            s.Scale = angularSperation / imageLength;
            double imageRotation = Math.Atan2(temp.X, temp.Y) / Math.PI * 180;
            double positionAngle = CAAAngularSeparation.PositionAngle(a.Celestial.RA, a.Celestial.Dec, b.Celestial.RA, b.Celestial.Dec);
            //          Earth3d.MainWindow.Text = "pa:" + positionAngle.ToString() + ", imrot:" + imageRotation.ToString() + ", scale:" + s.Scale.ToString();
            s.Rotation = -((imageRotation - positionAngle));
            double rotationRads = s.Rotation / 180 * Math.PI;
            s.OffsetX = width / 2;
            s.OfsetY = height / 2;

            // Calculate center point
            Vector2d centerDistA = center - a.Image;
            Vector2d centerDistB = center - b.Image;
            double centerRotaionA = Math.Atan2(centerDistA.X, centerDistA.Y);
            double centerRotaionB = Math.Atan2(centerDistB.X, centerDistB.Y);
            double raA = a.Celestial.RA + (Math.Sin(centerRotaionA + rotationRads) * s.Scale / 15 * centerDistA.Length / Math.Cos(a.Celestial.Dec / 180 * Math.PI));
            double raB = b.Celestial.RA + (Math.Sin(centerRotaionB + rotationRads) * s.Scale / 15 * centerDistB.Length / Math.Cos(b.Celestial.Dec / 180 * Math.PI));
            double decA = a.Celestial.Dec + (Math.Cos(centerRotaionA + rotationRads) * s.Scale * centerDistA.Length);
            double decB = b.Celestial.Dec + (Math.Cos(centerRotaionB + rotationRads) * s.Scale * centerDistB.Length);

            s.CenterX = (raA + raB) / 2;
            s.CenterY = (decA + decB) / 2;

            s.Flip = false;

            return s;
        }
        public override bool Draw(RenderContext11 renderContext, float opacity, bool flat)
        {
            Matrix3d oldWorld = renderContext.World;
            Matrix3d rotation = Matrix3d.RotationZ(-roll / 180f * Math.PI) * Matrix3d.RotationX(-pitch / 180f * Math.PI) * Matrix3d.RotationY(heading / 180f * Math.PI);

            renderContext.World = rotation * Matrix3d.Scaling(scale.X, scale.Y, scale.Z) * Matrix3d.Translation(translate) * oldWorld;
            renderContext.TwoSidedLighting = TwoSidedGeometry;
            renderContext.setRasterizerState(TwoSidedGeometry ? TriangleCullMode.Off : TriangleCullMode.CullCounterClockwise);
            if (lightID > 0)
            {
                //draw light

             //   Planets.DrawPointPlanet(renderContext, new Vector3d(), 1, Color, false, 1.0f);
            }
            else
            {
                if (object3d != null)
                {
                    object3d.Color = Color;
                    object3d.Render(renderContext, opacity * Opacity);
                }
            }
            renderContext.setRasterizerState(TriangleCullMode.CullCounterClockwise);
            renderContext.TwoSidedLighting = false;

            if (showEditUi)
            {
                if (lightID > 0)
                {
                    //draw light

                    Planets.DrawPointPlanet(renderContext, new Vector3d(), 1, Color, false, 1.0f);
                }

                DepthStencilMode oldDepthMode = renderContext.DepthStencilMode = DepthStencilMode.Off;
                renderContext.World = Matrix3d.Translation(translate) * oldWorld;

                Matrix3d wvp = renderContext.World * renderContext.View * renderContext.Projection;

                Vector3d vc = new Vector3d(0, 0, 0);
                Vector3d vc1 = new Vector3d(.001, 0, 0);
                Vector3d vc2 = new Vector3d(0, .001, 0);
                Vector3d vc3 = new Vector3d(0, 0, .001);
                Vector3d vs = Vector3d.TransformCoordinate(vc, wvp);
                Vector3d vs1 = Vector3d.TransformCoordinate(vc1, wvp);
                Vector3d vs2 = Vector3d.TransformCoordinate(vc2, wvp);
                Vector3d vs3 = Vector3d.TransformCoordinate(vc3, wvp);

                Vector2d vsa = new Vector2d(vs.X, vs.Y);
                Vector2d vsa1 = new Vector2d(vs1.X, vs1.Y) - vsa;
                Vector2d vsa2 = new Vector2d(vs2.X, vs2.Y) - vsa;
                Vector2d vsa3 = new Vector2d(vs3.X, vs3.Y) - vsa;

                uiScale = .0003 / Math.Sqrt((vsa1.Length * vsa1.Length + vsa2.Length * vsa2.Length + vsa3.Length * vsa3.Length));

                Matrix3d matUIScale = Matrix3d.Scaling(uiScale, uiScale, uiScale);

                renderContext.World = matUIScale * renderContext.World;

                wvp = renderContext.World * renderContext.View * renderContext.Projection;

                vc1 = new Vector3d(.9, 0, 0);
                vc2 = new Vector3d(0, .9, 0);
                vc3 = new Vector3d(0, 0, .9);
                vs = Vector3d.TransformCoordinate(vc, wvp);
                vs1 = Vector3d.TransformCoordinate(vc1, wvp);
                vs2 = Vector3d.TransformCoordinate(vc2, wvp);
                vs3 = Vector3d.TransformCoordinate(vc3, wvp);

                double h = renderContext.ViewPort.Height;
                double w = renderContext.ViewPort.Width;

                xHandle = new Vector2d((vs1.X + 1) * w / 2, h - ((vs1.Y + 1) * h / 2));
                yHandle = new Vector2d((vs2.X + 1) * w / 2, h - ((vs2.Y + 1) * h / 2));
                zHandle = new Vector2d((vs3.X + 1) * w / 2, h - ((vs3.Y + 1) * h / 2));

                // draw UI
                if (TranslateUI == null)
                {
                    InitTranslateUI();

                }

                bool showTranslate = Control.ModifierKeys != Keys.Control && Control.ModifierKeys != Keys.Shift;
                bool showRotate = Control.ModifierKeys == Keys.Control;
                bool showScale = Control.ModifierKeys == Keys.Shift;

                if (showTranslate)
                {
                    TranslateUILines.DrawLines(renderContext, 1.0f);

                    TranslateUI.Draw(renderContext, 1.0f, TriangleList.CullMode.Clockwise);
                }
                else
                {
                    if (showScale)
                    {
                        TranslateUILines.DrawLines(renderContext, 1.0f);
                        ScaleUI.Draw(renderContext, 1.0f, TriangleList.CullMode.Clockwise);
                    }
                    else
                    {
                        xHandle = new Vector2d(-1000, 0);
                        yHandle = new Vector2d(-1000, 0);
                        zHandle = new Vector2d(-1000, 0);
                    }
                }

                renderContext.World = rotation * renderContext.World;

                if (showRotate)
                {
                    wvp = renderContext.World * renderContext.View * renderContext.Projection;

                    Vector3d[] hprPoints = new Vector3d[]
                                    {
                                        new Vector3d(0,0,1),
                                        new Vector3d(0,0,-1),
                                        new Vector3d(0,1,0),
                                        new Vector3d(0,-1,0),
                                        new Vector3d(-1,0,0),
                                        new Vector3d(1,0,0)
                                    };
                    hprHandles = new Vector2d[6];
                    for (int i = 0; i < 6; i++)
                    {
                        Vector3d vt = Vector3d.TransformCoordinate(hprPoints[i], wvp);
                        hprHandles[i] = new Vector2d((vt.X + 1) * w / 2, h - ((vt.Y + 1) * h / 2));
                    }

                    RotateUi.Draw(renderContext, 1.0f, TriangleList.CullMode.Clockwise);
                }
                else
                {
                    hprHandles = new Vector2d[0];
                }

                oldDepthMode = renderContext.DepthStencilMode = oldDepthMode;

                //restore matrix
                renderContext.World = oldWorld;
                showEditUi = false;
            }
            renderContext.World = oldWorld;

            return true;
        }
        private WcsSolution Solve(CorresponencePoint a, CorresponencePoint b)
        {
            WcsSolution s = new WcsSolution();
            Vector2d center = new Vector2d(width / 2, height / 2);
            Vector2d temp = a.Image - b.Image;
            double imageLength = temp.Length;
            double angularSperation = CAAAngularSeparation.Separation(a.Celestial.RA, a.Celestial.Dec, b.Celestial.RA, b.Celestial.Dec);

            // Degrees per pixel
            s.Scale = angularSperation / imageLength;
            double imageRotation = Math.Atan2(temp.X, temp.Y) / Math.PI * 180;

            temp = center - b.Image;

            double centerRotation = Math.Atan2(temp.X, temp.Y) / Math.PI * 180;

            s.OffsetX = width / 2;
            s.OfsetY = height / 2;

            Coordinates cent = a.Celestial;

            int iters = 4;

            while (iters-- > 0)
            {

                // Calculate Center
                Vector2d tanA = Coordinates.RaDecToTan(cent, a.Celestial);
                Vector2d tanB = Coordinates.RaDecToTan(cent, b.Celestial);

                temp = tanA - tanB;
                double tanLength = temp.Length;

                s.Scale = (tanLength/Math.PI*180) / imageLength;

                double tanRotation = Math.Atan2(temp.X, temp.Y) / Math.PI * 180;

                double tRotRad = -((imageRotation - tanRotation) / 180 * Math.PI);

                Vector2d centerDistA = center - a.Image;
                double centerRotaionA = Math.Atan2(centerDistA.X, centerDistA.Y);

                double ratio = tanLength / imageLength;

                double tanCx = tanA.X + Math.Sin(centerRotaionA + tRotRad) * ratio * centerDistA.Length;
                double tanCy = tanA.Y + Math.Cos(centerRotaionA + tRotRad) * ratio * centerDistA.Length;

                Vector2d result = Coordinates.TanToRaDec(cent, new Vector2d(tanCx, tanCy));
                s.CenterX = result.X;
                s.CenterY = result.Y;

                cent = Coordinates.FromRaDec(result.X, result.Y);
            }

            double positionAngle = CAAAngularSeparation.PositionAngle(s.CenterX, s.CenterY, b.Celestial.RA, b.Celestial.Dec);
            s.Rotation = -((centerRotation - positionAngle));

            s.Flip = false;

            return s;
        }
 public CorresponencePoint(Coordinates celetial, Vector2d image)
 {
     Celestial = celetial;
     Image = image;
 }
        public static void FindEnclosingCircle(Vector2d[] list, out Vector2d cen, out double rad)
        {
            cen = new Vector2d();
            var count = list.Length;
            int i;
            var xmin = new Vector2d();
            var xmax = new Vector2d();
            var ymin = new Vector2d();
            var ymax = new Vector2d();
            var dia1 = new Vector2d();
            var dia2 = new Vector2d();

            // FIRST PASS: find 6 minima/maxima points
            xmin.X = ymin.Y = 100000000; // initialize for min/max compare
            xmax.X = ymax.Y = -1000000000;
            for (i = 0; i < count; i++)
            {
                var current = list[i];
                // his ith point.
                if (current.X < xmin.X)
                    xmin = current; // New xminimum point
                if (current.X > xmax.X)
                    xmax = current;
                if (current.Y < ymin.Y)
                    ymin = current;
                if (current.Y > ymax.Y)
                    ymax = current;

            }
            // Set xspan = distance between the 2 points xmin & xmax (squared)
            double dx = xmax.X - xmin.X;
            double dy = xmax.Y - xmin.Y;
            double xspan = dx * dx + dy * dy;

            // Same for y & z spans
            dx = ymax.X - ymin.X;
            dy = ymax.Y - ymin.Y;
            double yspan = dx * dx + dy * dy;

            dia1 = xmin; // assume xspan biggest
            dia2 = xmax;
            double maxspan = xspan;
            if (yspan > maxspan)
            {
                maxspan = yspan;
                dia1 = ymin;
                dia2 = ymax;
            }

            // dia1,dia2 is a diameter of initial sphere
            // calc initial center
            cen.X = (dia1.X + dia2.X) / 2.0;
            cen.Y = (dia1.Y + dia2.Y) / 2.0;
            // calculate initial radius**2 and radius
            dx = dia2.X - cen.X; // x component of radius vector
            dy = dia2.Y - cen.Y; // y component of radius vector
            double rad_sq = dx * dx + dy * dy;
            rad = Math.Sqrt(rad_sq);

            // SECOND PASS: increment current sphere

            for (i = 0; i < count; i++)
            {
                var current = list[i]; // load global struct caller_p
                // with his ith point.
                dx = current.X - cen.X;
                dy = current.Y - cen.Y;
                double old_to_p_sq = dx * dx + dy * dy;
                if (old_to_p_sq > rad_sq) // do r**2 test first
                { // this point is outside of current sphere
                    double old_to_p = Math.Sqrt(old_to_p_sq);
                    // calc radius of new sphere
                    rad = (rad + old_to_p) / 2.0;
                    rad_sq = rad * rad; // for next r**2 compare
                    double old_to_new = old_to_p - rad;
                    // calc center of new sphere
                    cen.X = (rad * cen.X + old_to_new * current.X) / old_to_p;
                    cen.Y = (rad * cen.Y + old_to_new * current.Y) / old_to_p;
                }
            }
        }
        public double Distance3d(Vector2d pointB)
        {
            var pnt1 = Coordinates.GeoTo3dDouble(pointB.Y, pointB.X);
            var pnt2 = Coordinates.GeoTo3dDouble(Y, X);

            var pntDiff = pnt1 - pnt2;

            return pntDiff.Length() /Math.PI * 180;
        }
 public static Vector2d Lerp(Vector2d left, Vector2d right, double interpolater)
 {
     if (Math.Abs(left.X - right.X) > 12)
     {
         if (left.X > right.X)
         {
             right.X += 24;
         }
         else
         {
             left.X += 24;
         }
     }
     return new Vector2d(left.X * (1 - interpolater) + right.X * interpolater, left.Y * (1 - interpolater) + right.Y * interpolater);
 }
        public static Vector2d TanToRaDec(Vector2d center, Vector2d point)
        {
            var x = point.X;
            var y = point.Y;
            var lcenter = center.X / 12 * Math.PI;
            var pCenter = center.Y / 180 * Math.PI;

            var p = Math.Sqrt(x * x + y * y);
            var c = Math.Atan(p);

            var phi = Math.Asin(Math.Cos(c) * Math.Sin(pCenter) + y * Math.Sin(c) * Math.Cos(pCenter) / p);

            var lambda = lcenter + Math.Atan2(x * Math.Sin(c), (p * Math.Cos(pCenter) * Math.Cos(c) - y * Math.Sin(pCenter) * Math.Sin(c)));

            return new Vector2d(lambda / Math.PI * 12, phi / Math.PI * 180);
        }
            public Coordinates Project(Vector2d point, double width, double height)
            {
                double lat = point.Y;
                double lng = point.X;
                lng = -lng;
                Matrix3d matrix = Matrix3d.Identity;
                matrix.Multiply(Matrix3d.RotationX((((Rotation-180)) / 180f * Math.PI)));
                matrix.Multiply(Matrix3d.RotationZ(((Dec) / 180f * Math.PI)));
                matrix.Multiply(Matrix3d.RotationY((((360 - RA*15) + 180) / 180f * Math.PI)));

                //lng = -lng;
                double fac1 = (Scale*height) / 2;
                double factor = Math.Tan(fac1 * RC);

                Vector3d retPoint = Vector3d.TransformCoordinate(new Vector3d(1f, (lat / fac1 * factor), (lng / fac1 * factor)), matrix);
                retPoint.Normalize();
                return Coordinates.CartesianToSpherical2(retPoint);
            }
        public Vector2d GetImagePixel(Coordinates sky)
        {
            var result = new Vector2d();
            //Vector3 tangent = GeoTo3dWithAltitude(sky.Lat, sky.Lng);
            var tangent = Coordinates.RADecTo3d(sky.RA + 12, sky.Dec, 1);
            var mat = dataset.Matrix;
            mat.Invert();

            tangent = Vector3d.TransformCoordinate(tangent, mat);

            var imagePoint = Coordinates.CartesianToSpherical(tangent);

            result.X = (float)((imagePoint.Lng / ScaleX) + PixelCenterX);
            result.Y = (float)((imagePoint.Lat / -ScaleY) + PixelCenterY);

             return result;
        }
 public void AddPoint(Coordinates sky, Vector2d image)
 {
     Points.Add(new CorresponencePoint(sky, image));
 }
        public bool MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            pntDown = e.Location;

            Vector2d pnt = new Vector2d(e.X, e.Y);

            if (Control.ModifierKeys == Keys.Shift)
            {
                if ((pnt - xHandle).Length < hitDist)
                {
                    dragMode = Draging.Scale;
                    valueOnDown = this.scale.X;
                    return true;
                }

                if ((pnt - yHandle).Length < hitDist)
                {
                    dragMode = Draging.Scale;
                    valueOnDown = this.scale.Y;
                    return true;
                }

                if ((pnt - zHandle).Length < hitDist)
                {
                    dragMode = Draging.Scale;
                    valueOnDown = this.scale.Z;
                    return true;
                }
            }
            else
            {
                if ((pnt - xHandle).Length < hitDist)
                {
                    dragMode = Draging.X;
                    valueOnDown = this.translate.X;
                    return true;
                }

                if ((pnt - yHandle).Length < hitDist)
                {
                    dragMode = Draging.Y;
                    valueOnDown = this.translate.Y;
                    return true;
                }

                if ((pnt - zHandle).Length < hitDist)
                {
                    dragMode = Draging.Z;
                    valueOnDown = this.translate.Z;
                    return true;
                }
            }

            for (int i = 0; i < hprHandles.Length; i++)
            {
                if ((pnt - hprHandles[i]).Length < hitDist)
                {
                    switch (i)
                    {
                        case 0:
                            dragMode = Draging.HP;
                            valueOnDown = this.heading;
                            valueOnDown2 = this.pitch;
                            return true;
                        case 1:
                            dragMode = Draging.HP1;
                            valueOnDown = this.heading;
                            valueOnDown2 = this.pitch;
                            return true;
                        case 2:
                            dragMode = Draging.PR;
                            valueOnDown = this.pitch;
                            valueOnDown2 = this.roll;
                            return true;
                        case 3:
                            dragMode = Draging.PR1;
                            valueOnDown = this.pitch;
                            valueOnDown2 = this.roll;
                            return true;
                        case 4:
                            dragMode = Draging.RH;
                            valueOnDown = this.roll;
                            valueOnDown2 = this.heading;
                            return true;
                        case 5:
                            dragMode = Draging.RH1;
                            valueOnDown = this.roll;
                            valueOnDown2 = this.heading;
                            return true;
                        default:
                            break;
                    }
                }
            }

            return false;
        }
        private void CurveEditor_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            int step = Width / 10;
            for (int x = 0; x <= Width; x += step)
            {
                g.DrawLine(Pens.Gray, x, 0, x, Height);
            }

            for (int y = 0; y <= Height; y += step)
            {
                g.DrawLine(Pens.Gray, 0, y, Width, y);
            }

            g.DrawLine(Pens.White, Width / 2, 0, Width / 2, Height);

            g.DrawLine(Pens.White, 0, Height / 2, Width, Height / 2);

            Vector2d first = new Vector2d(0, 0);
            Vector2d control1 = new Vector2d(P1, P2);
            Vector2d control2 = new Vector2d(P3, P4);
            Vector2d last = new Vector2d(1, 1);

            Vector2d pnt1 = first;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            float w = Width - 1;

            for (double tween = 0; tween <= 1.05; tween += (1 / 44.0))
            {
                Vector2d pnt2 = ComputeSpline(first, control1, control2, last, tween);
                g.DrawLine(Pens.White, (float)pnt1.X * w, w - (float)pnt1.Y * w, (float)pnt2.X * w, w - (float)pnt2.Y * w);
                pnt1 = pnt2;
            }

            if (CurveType == Key.KeyType.Custom)
            {
                g.DrawLine(Pens.Yellow, 0, w, (float)P1 * w, w - (float)P2 * w);
                g.DrawLine(Pens.Yellow, w, 0, (float)P3 * w, w - (float)P4 * w);
                g.DrawRectangle(Pens.Yellow, ((float)P1 * w) - 4, (w - (float)P2 * w) - 4, 8, 8);
                g.DrawRectangle(Pens.Yellow, ((float)P3 * w) - 4, (w - (float)P4 * w) - 4, 8, 8);
            }
        }
Beispiel #20
0
        private bool ProcessKioskControls(MouseEventArgs e)
        {
            activeTouch = TouchControls.None;
            timer.Enabled = false;
            if (Properties.Settings.Default.ShowTouchControls)
            {
                MakeTouchPoints();

                int tX = e.X + Properties.Settings.Default.ScreenHitTestOffsetX;
                int tY = e.Y + Properties.Settings.Default.ScreenHitTestOffsetY;

                if (tX > (renderWindow.Width - 207) && tX < (renderWindow.Width - 10))
                {
                    if (tY > renderWindow.Height - (234 + 120) && tY < (renderWindow.Height - 10))
                    {
                        moveVector = new PointF();
                        Point hit = PointToTouch(new Point(tX, tY));
                        for (int i = 0; i < touchPoints.Count; i++)
                        {
                            Vector2d test = new Vector2d(hit.X, hit.Y);
                            test = test - touchPoints[i];
                            if (test.Length < 11)
                            {
                                activeTouch = (TouchControls)i;
                                if (activeTouch == TouchControls.TrackBall)
                                {
                                    touchTrackBallCenter = new Point(tX, tY);
                                }
                                timer.Enabled = true;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
        private Vector2d ComputeSpline(Vector2d begin, Vector2d control1, Vector2d control2, Vector2d end, double tween)
        {
            if (curveType == Key.KeyType.Custom)
            {
                Vector2d A1 = Vector2d.Lerp(begin, control1, tween);
                Vector2d A2 = Vector2d.Lerp(control1, control2, tween);
                Vector2d A3 = Vector2d.Lerp(control2, end, tween);

                Vector2d B1 = Vector2d.Lerp(A1, A2, tween);
                Vector2d B2 = Vector2d.Lerp(A2, A3, tween);
                return Vector2d.Lerp(B1, B2, tween);
            }
            else
            {
                return new Vector2d(tween, Key.EaseCurve(curveType, tween, control1.X, control1.Y, control2.X, control2.Y));
            }
        }
Beispiel #22
0
 private Vector2d TouchToScreen(Vector2d pnt)
 {
     return new Vector2d(pnt.X + (renderWindow.Width - 207), pnt.Y + (renderWindow.Height - (234 + 120)));
 }
        public static Vector2d RaDecToTan(Vector2d center, Vector2d point)
        {
            double lambda = point.X / 12 * Math.PI;
            double phi = point.Y / 180 * Math.PI;
            double lcenter = center.X / 12 * Math.PI;
            double pCenter = center.Y / 180 * Math.PI;

            double cosc = Math.Sin(pCenter) * Math.Sin(phi) + Math.Cos(pCenter) * Math.Cos(phi) * Math.Cos(lambda - lcenter);

            double x = Math.Cos(phi) * Math.Sin(lambda - lcenter) / cosc;
            double y = (Math.Cos(pCenter) * Math.Sin(phi) - Math.Sin(pCenter) * Math.Cos(phi) * Math.Cos(lambda - lcenter)) / cosc;

            return new Vector2d(x, y);
        }
Beispiel #24
0
        private void DrawTouchControls()
        {

            if (Properties.Settings.Default.ShowTouchControls && !TourEditor.Capturing && !CaptureVideo)
            {

                MakeTouchPoints();

                if (trackerButton == null)
                {
                    trackerButton = Planets.LoadPlanetTexture(Properties.Resources.TrackerButton);
                }

                if (touchControl == null)
                {
                    string appdir = Path.GetDirectoryName(Application.ExecutablePath);
                    string customImageFile = appdir + "\\TouchControls.png";
                    string customImageFileNoHold = appdir + "\\TouchControlsNoHold.png";
                    if (File.Exists(customImageFile))
                    {
                        Bitmap bmp = new Bitmap(customImageFile);
                        touchControl = Planets.LoadPlanetTexture(bmp); 
                        bmp.Dispose();
                    }
                    else
                    {
                        touchControl = Planets.LoadPlanetTexture(Properties.Resources.TouchControls);
                    }

                    if (File.Exists(customImageFileNoHold))
                    {
                        Bitmap bmp = new Bitmap(customImageFileNoHold);
                        touchControlNoHold = Planets.LoadPlanetTexture(bmp); 
                        bmp.Dispose();
                    }
                    else
                    {
                        touchControlNoHold = Planets.LoadPlanetTexture(Properties.Resources.TouchControlsNoHold);
                    }

                }

                float x = RenderContext11.ViewPort.Width - 207;
                float y = RenderContext11.ViewPort.Height - (234 + 120);
                float w = 197;
                float h = 224;

                TouchControlPoints[0].X = x;
                TouchControlPoints[0].Y = y;
                TouchControlPoints[0].Z = .9f;
                TouchControlPoints[0].W = 1;
                TouchControlPoints[0].Tu = 0;
                TouchControlPoints[0].Tv = 0;
                TouchControlPoints[0].Color = Color.FromArgb(64, 255, 255, 255);

                TouchControlPoints[1].X = (float)(x + w);
                TouchControlPoints[1].Y = (float)(y);
                TouchControlPoints[1].Tu = 1;
                TouchControlPoints[1].Tv = 0;
                TouchControlPoints[1].Color = Color.FromArgb(64, 255, 255, 255);
                TouchControlPoints[1].Z = .9f;
                TouchControlPoints[1].W = 1;

                TouchControlPoints[2].X = (float)(x);
                TouchControlPoints[2].Y = (float)(y + h);
                TouchControlPoints[2].Tu = 0;
                TouchControlPoints[2].Tv = 1;
                TouchControlPoints[2].Color = Color.FromArgb(64, 255, 255, 255);
                TouchControlPoints[2].Z = .9f;
                TouchControlPoints[2].W = 1;

                TouchControlPoints[3].X = (float)(x + w);
                TouchControlPoints[3].Y = (float)(y + h);
                TouchControlPoints[3].Tu = 1;
                TouchControlPoints[3].Tv = 1;
                TouchControlPoints[3].Color = Color.FromArgb(64, 255, 255, 255);
                TouchControlPoints[3].Z = .9f;
                TouchControlPoints[3].W = 1;

                if (Friction)
                {
                    Sprite2d.DrawForScreen(RenderContext11, TouchControlPoints, 4, touchControlNoHold, SharpDX.Direct3D.PrimitiveTopology.TriangleStrip);
                }
                else
                {
                    Sprite2d.DrawForScreen(RenderContext11, TouchControlPoints, 4, touchControl, SharpDX.Direct3D.PrimitiveTopology.TriangleStrip);
                }

                if (!kioskControl)
                {
                    if (Friction && activeTouch == TouchControls.None)
                    {
                        float frictionFactor = (float)(1 - (lastFrameTime / 2));
                        moveVector.X *= frictionFactor;
                        moveVector.Y *= frictionFactor;
                        OrbitVector *= frictionFactor;
                        ZoomVector *= frictionFactor;
                    }


                    // Calculate Arc for Zoom
                    Vector2d zoomArc = new Vector2d(zoomTracker.X - ZoomVector, (zoomTracker.Y - Math.Cos(ZoomVector / 54 * Math.PI / 2) * 20) + 39);
                    touchPoints[(int)TouchControls.ZoomTrack] = zoomArc;

                    // Calculate Arc for Orbit
                    Vector2d orbitArc = new Vector2d(99 - (Math.Sin(OrbitVector / 70 * Math.PI / 2) * 68), 113 + (Math.Cos(OrbitVector / 70 * Math.PI / 2) * 75));
                    touchPoints[(int)TouchControls.OrbitTrack] = orbitArc;

                    // Calculate Current Pan Position
                    Vector2d panPos = new Vector2d(panTracker.X - moveVector.X, panTracker.Y - moveVector.Y);

                    touchPoints[(int)TouchControls.PanTrack] = panPos;

                    Sprite2d.Draw2D(RenderContext11, trackerButton, new SizeF(32, 32), new PointF(15, 15), 0, new PointF((float)touchPoints[(int)TouchControls.PanTrack].X + x, (float)touchPoints[(int)TouchControls.PanTrack].Y + y), Color.FromArgb(128, 255, 255, 255));
                    Sprite2d.Draw2D(RenderContext11, trackerButton, new SizeF(32, 32), new PointF(15, 15), 0, new PointF((float)touchPoints[(int)TouchControls.OrbitTrack].X + x, (float)touchPoints[(int)TouchControls.OrbitTrack].Y + y), Color.FromArgb(128, 255, 255, 255));
                    Sprite2d.Draw2D(RenderContext11, trackerButton, new SizeF(32, 32), new PointF(15, 15), 0, new PointF((float)touchPoints[(int)TouchControls.ZoomTrack].X + x, (float)touchPoints[(int)TouchControls.ZoomTrack].Y + y), Color.FromArgb(128, 255, 255, 255));
                }
            }
        }
        public static Vector2d RaDecToTan(Vector2d center, Vector2d point)
        {
            var lambda = point.X / 12 * Math.PI;
            var phi = point.Y / 180 * Math.PI;
            var lcenter = center.X / 12 * Math.PI;
            var pCenter = center.Y / 180 * Math.PI;

            var cosc = Math.Sin(pCenter) * Math.Sin(phi) + Math.Cos(pCenter) * Math.Cos(phi) * Math.Cos(lambda - lcenter);

            var x = Math.Cos(phi) * Math.Sin(lambda - lcenter) / cosc;
            var y = (Math.Cos(pCenter) * Math.Sin(phi) - Math.Sin(pCenter) * Math.Cos(phi) * Math.Cos(lambda - lcenter)) / cosc;

            return new Vector2d(x, y);
        }
Beispiel #26
0
        private Vector2d ComputeSpline(Vector2d begin, Vector2d control1, Vector2d control2, Vector2d end, double tween)
        {
            var A1 = Vector2d.Lerp(begin, control1, tween);
            var A2 = Vector2d.Lerp(control1, control2, tween);
            var A3 = Vector2d.Lerp(control2, end, tween);

            var B1 = Vector2d.Lerp(A1, A2, tween);
            var B2 = Vector2d.Lerp(A2, A3, tween);
            return Vector2d.Lerp(B1, B2, tween);
        }
        private bool ProcessTouchControls(MouseEventArgs e)
        {
            activeTouch = TouchControls.None;
            if (Properties.Settings.Default.ShowTouchControls)
            {
                MakeTouchPoints();

                var tX = e.X + Properties.Settings.Default.ScreenHitTestOffsetX;
                var tY = e.Y + Properties.Settings.Default.ScreenHitTestOffsetY;

                if (tX > (renderWindow.Width - 207) && tX < (renderWindow.Width - 10))
                {
                    if (tY > renderWindow.Height - (234 + 120 + 30) && tY < (renderWindow.Height - 10))
                    {

                        var hit = new Point(tX - (renderWindow.Width - 207), tY - (renderWindow.Height - (234 + 120)));

                        for (var i = touchPoints.Count - 1; i >= 0; i--)
                        {
                            var test = new Vector2d(hit.X, hit.Y);
                            test = test - touchPoints[i];
                            if (test.Length < 15)
                            {
                                activeTouch = (TouchControls)i;
                                if (activeTouch == TouchControls.TrackBall)
                                {
                                    touchTrackBallCenter = new Point(tX, tY);
                                    moveVector = new PointF();
                                    touchPoints[(int)TouchControls.PanTrack] = panTracker;
                                }
                                timer.Enabled = true;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }