示例#1
0
        public void HorizontalToEquatorial()
        {
            // Apparent local horizontal coordinates of Venus
            var hor = new CrdsHorizontal(68.0337, 15.1249);

            // Geographical coordinates of US Naval Observatory at Washington, DC
            var geo = new CrdsGeographical(new DMS("+38* 55' 17''"), new DMS("+77* 03' 56''"));

            // Date of observation
            var jd = new Date(new DateTime(1987, 4, 10, 19, 21, 0, DateTimeKind.Utc)).ToJulianDay();

            // Nutation elements
            var nutation = Nutation.NutationElements(jd);

            // True obliquity
            var epsilon = Date.TrueObliquity(jd, nutation.deltaEpsilon);

            // Apparent sidereal time at Greenwich
            var theta0 = Date.ApparentSiderealTime(jd, nutation.deltaPsi, epsilon);

            Assert.AreEqual(new HMS("8h 34m 56.853s"), new HMS(theta0));

            // Expected apparent equatorial coordinates of Venus
            var eqExpected = new CrdsEquatorial(new HMS("23h 09m 16.641s"), new DMS("-6* 43' 11.61''"));

            // Tested value
            var eqActual = hor.ToEquatorial(geo, theta0);

            Assert.AreEqual(eqExpected.Alpha, eqActual.Alpha, errorInHMS);
            Assert.AreEqual(eqExpected.Delta, eqActual.Delta, errorInDMS);
        }
示例#2
0
        public void GoToObject(CelestialObject body, TimeSpan animationDuration)
        {
            double sd = (body is SizeableCelestialObject) ?
                        (body as SizeableCelestialObject).Semidiameter / 3600 : 0;

            double viewAngleTarget = sd == 0 ? 1 : Math.Max(sd * 10, MIN_VIEW_ANGLE);

            if (animationDuration.Equals(TimeSpan.Zero))
            {
                Center.Set(body.Horizontal);
                ViewAngle = viewAngleTarget;
            }
            else
            {
                CrdsHorizontal centerOriginal = new CrdsHorizontal(Center);
                double         ad             = Angle.Separation(body.Horizontal, centerOriginal);
                double         steps          = Math.Round(animationDuration.TotalMilliseconds / meanRenderTime);
                double[]       x = new double[] { 0, steps / 2, steps };
                double[]       y = (ad < ViewAngle) ?
                                   // linear zooming if body is already on the screen:
                                   new double[] { ViewAngle, (ViewAngle + viewAngleTarget) / 2, viewAngleTarget } :
                // parabolic zooming with jumping to 90 degrees view angle at the middle of path:
                new double[] { ViewAngle, 90, viewAngleTarget };

                for (int i = 0; i <= steps; i++)
                {
                    Center.Set(Angle.Intermediate(centerOriginal, body.Horizontal, i / steps));
                    ViewAngle = Math.Min(90, Interpolation.Lagrange(x, y, i));
                }
            }
        }
示例#3
0
        /// <summary>
        /// Does the rendering logic
        /// </summary>
        /// <param name="map">Map instance</param>
        public override void Render(IMapContext map)
        {
            if (IsMeasureToolOn && map.MousePosition != null)
            {
                double coeff = map.DiagonalCoefficient();

                List <PointF> points = new List <PointF>();
                for (int f = 0; f <= 10; f++)
                {
                    CrdsHorizontal h = Angle.Intermediate(map.MousePosition, MeasureOrigin, f / 10.0);
                    points.Add(map.Project(h));
                    if (Angle.Separation(h, map.Center) > map.ViewAngle * coeff)
                    {
                        break;
                    }
                }

                if (points.Count > 1)
                {
                    map.Graphics.DrawCurve(new Pen(map.GetColor(Color.White)), points.ToArray());
                    double angle = Angle.Separation(map.MousePosition, MeasureOrigin);
                    PointF p     = map.Project(map.MousePosition);
                    map.Graphics.DrawString(Formatters.MeasuredAngle.Format(angle), fontAngleValue, new SolidBrush(map.GetColor(Color.White)), p.X + 5, p.Y + 5);
                }
            }
        }
示例#4
0
        public void Intermediate()
        {
            CrdsHorizontal h1 = new CrdsHorizontal(5, 52);
            CrdsHorizontal h2 = new CrdsHorizontal(-120, 37);

            var expected = new CrdsHorizontal[]
            {
                new CrdsHorizontal(5, 52),
                new CrdsHorizontal(-9.924971, 59.60085),
                new CrdsHorizontal(-31.666402, 64.65469),
                new CrdsHorizontal(-58.557896, 65.51770),
                new CrdsHorizontal(-82.746574, 61.80095),
                new CrdsHorizontal(-99.938739, 54.93700),
                new CrdsHorizontal(-111.623334, 46.39746),
                new CrdsHorizontal(-120.000000, 37.00000)
            };

            for (int i = 0; i <= 7; i++)
            {
                var h = Angle.Intermediate(h1, h2, i / 7.0);

                var altExpected = expected[i].Altitude;
                var azExpected  = expected[i].Azimuth;

                Assert.AreEqual(altExpected, h.Altitude, 1e-5);
                Assert.AreEqual(azExpected, h.Azimuth, 1e-5);
            }
        }
示例#5
0
        public PointF Project(CrdsHorizontal hor)
        {
            double X, Y;

            double d  = Angle.ToRadians(hor.Altitude);
            double d0 = Angle.ToRadians(Map.Center.Altitude);
            double da = Angle.ToRadians(hor.Azimuth - Map.Center.Azimuth);

            double sin_da = Math.Sin(da);
            double cos_da = Math.Cos(da);

            double sin_d = Math.Sin(d);
            double cos_d = Math.Cos(d);

            double sin_d0 = Math.Sin(d0);
            double cos_d0 = Math.Cos(d0);

            X = cos_d * sin_da;
            Y = sin_d * cos_d0 - cos_d * sin_d0 * cos_da;

            double r = Math.Sqrt(Map.Width * Map.Width + Map.Height * Map.Height);

            X = X * 90 / Map.ViewAngle / 2 * r;
            Y = Y * 90 / Map.ViewAngle / 2 * r;

            return(new Point((int)(Map.Width / 2.0 + X), (int)(Map.Height / 2.0 - Y)));
        }
示例#6
0
        public void GoToPoint(CrdsHorizontal hor, TimeSpan animationDuration, double viewAngleTarget)
        {
            if (viewAngleTarget == 0)
            {
                viewAngleTarget = ViewAngle;
            }

            if (animationDuration.Equals(TimeSpan.Zero))
            {
                Center.Set(hor);
                ViewAngle = viewAngleTarget;
            }
            else
            {
                CrdsHorizontal centerOriginal = new CrdsHorizontal(Center);
                double         ad             = Angle.Separation(hor, centerOriginal);
                double         steps          = Math.Ceiling(animationDuration.TotalMilliseconds / meanRenderTime);
                double[]       x = new double[] { 0, steps / 2, steps };
                double[]       y = (ad < ViewAngle) ?
                                   // linear zooming if body is already on the screen:
                                   new double[] { ViewAngle, (ViewAngle + viewAngleTarget) / 2, viewAngleTarget } :
                // parabolic zooming with jumping to 90 degrees view angle at the middle of path:
                new double[] { ViewAngle, 90, viewAngleTarget };

                for (int i = 0; i <= steps; i++)
                {
                    Center.Set(Angle.Intermediate(centerOriginal, hor, i / steps));
                    ViewAngle = Math.Min(90, Interpolation.Lagrange(x, y, i));
                }
            }
        }
示例#7
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            Select();

            if (SkyMap != null)
            {
                bool shift = (ModifierKeys & Keys.Shift) != Keys.None;

                if (e.Button == MouseButtons.Left && !shift)
                {
                    isMouseMoving = true;

                    pNew.X = e.X;
                    pNew.Y = e.Y;
                    double dx = pNew.X - pOld.X;
                    double dy = pNew.Y - pOld.Y;

                    double f = SkyMap.Width / (SkyMap.ViewAngle * 2);

                    if (Math.Abs(SkyMap.Center.Altitude) < 30 || SkyMap.ViewAngle > 80)
                    {
                        SkyMap.Center.Azimuth = (SkyMap.Center.Azimuth - dx / f + 360) % 360;
                    }
                    else
                    {
                        CrdsHorizontal cpNew = SkyMap.Projection.Invert(pNew);
                        CrdsHorizontal cpOld = SkyMap.Projection.Invert(pOld);
                        double         da    = Math.Abs(cpNew.Azimuth - cpOld.Azimuth);
                        da = Math.Abs(da) * Math.Sign(dx);
                        SkyMap.Center.Azimuth -= da;
                        SkyMap.Center.Azimuth %= 360;
                    }

                    SkyMap.Center.Altitude += dy / f;

                    if (SkyMap.Center.Altitude > 90)
                    {
                        SkyMap.Center.Altitude = 90;
                    }
                    if (SkyMap.Center.Altitude < -90)
                    {
                        SkyMap.Center.Altitude = -90;
                    }

                    if (double.IsNaN(SkyMap.Center.Azimuth))
                    {
                        SkyMap.Center.Azimuth = 0;
                    }

                    pOld.X = pNew.X;
                    pOld.Y = pNew.Y;

                    Invalidate();
                }
            }
        }
示例#8
0
        public PointF Project(CrdsHorizontal hor)
        {
            // ARC projection, AIPS MEMO 27
            // Zenith Equidistant Projection

            double X, Y, L, M;

            double d   = Angle.ToRadians(hor.Altitude);
            double d0  = Angle.ToRadians(Map.Center.Altitude);
            double da  = Angle.ToRadians(hor.Azimuth - Map.Center.Azimuth);
            double rho = Angle.ToRadians(0);

            double sin_da = Math.Sin(da);
            double cos_da = Math.Cos(da);

            double sin_d = Math.Sin(d);
            double cos_d = Math.Cos(d);

            double sin_d0 = Math.Sin(d0);
            double cos_d0 = Math.Cos(d0);

            double theta = Math.Acos(sin_d * sin_d0 + cos_d * cos_d0 * cos_da);

            if (theta == 0 || double.IsNaN(theta))
            {
                X = 0;
                Y = 0;
                return(new PointF((float)(Map.Width / 2.0 + X), (float)(Map.Height / 2.0 - Y)));
            }

            double k = theta / Math.Sin(theta);

            L = k * cos_d * sin_da;
            M = k * (sin_d * cos_d0 - cos_d * sin_d0 * cos_da);

            double sin_rho = Math.Sin(rho);
            double cos_rho = Math.Cos(rho);

            X = L * cos_rho + M * sin_rho;
            Y = M * cos_rho - L * sin_rho;

            X = Angle.ToDegrees(X) / Map.ViewAngle * Map.Width / 2;
            Y = Angle.ToDegrees(Y) / Map.ViewAngle * Map.Width / 2;

            return(new Point((int)(Map.Width / 2.0 + X), (int)(Map.Height / 2.0 - Y)));
        }
示例#9
0
        public PointF Project(CrdsHorizontal hor)
        {
            double X, Y;

            double d  = (IsInverted ? -1 : 1) * Angle.ToRadians(hor.Altitude);
            double d0 = (IsInverted ? -1 : 1) * Angle.ToRadians(Map.Center.Altitude);
            double da = (IsMirrored ? -1 : 1) * Angle.ToRadians(hor.Azimuth - Map.Center.Azimuth);

            double sin_da = Math.Sin(da);
            double cos_da = Math.Cos(da);

            double sin_d = Math.Sin(d);
            double cos_d = Math.Cos(d);

            double sin_d0 = Math.Sin(d0);
            double cos_d0 = Math.Cos(d0);

            double theta = Math.Acos(sin_d * sin_d0 + cos_d * cos_d0 * cos_da);

            if (theta == 0 || double.IsNaN(theta))
            {
                X = 0;
                Y = 0;
                return(new PointF((float)(Map.Width / 2.0 + X), (float)(Map.Height / 2.0 - Y)));
            }

            double k = theta / Math.Sin(theta);

            X = k * cos_d * sin_da;
            Y = k * (sin_d * cos_d0 - cos_d * sin_d0 * cos_da);

            double maxSize = Math.Sqrt(Map.Width * Map.Width + Map.Height * Map.Height);

            X = Angle.ToDegrees(X) / Map.ViewAngle * maxSize / 2;
            Y = Angle.ToDegrees(Y) / Map.ViewAngle * maxSize / 2;

            return(new Point((int)(Map.Width / 2.0 + X), (int)(Map.Height / 2.0 - Y)));
        }
示例#10
0
 public void Separation()
 {
     // Example 17.a, AA(II)
     {
         var c1 = new CrdsEquatorial(213.9154, 19.1825);
         var c2 = new CrdsEquatorial(201.2983, -11.1614);
         Assert.AreEqual(32.7930, Angle.Separation(c1, c2), 1e-4);
     }
     {
         var c1 = new CrdsEcliptical(213.9154, 19.1825);
         var c2 = new CrdsEcliptical(201.2983, -11.1614);
         Assert.AreEqual(32.7930, Angle.Separation(c1, c2), 1e-4);
     }
     {
         var c1 = new CrdsGeographical(213.9154, 19.1825);
         var c2 = new CrdsGeographical(201.2983, -11.1614);
         Assert.AreEqual(32.7930, Angle.Separation(c1, c2), 1e-4);
     }
     {
         var c1 = new CrdsHorizontal(213.9154, 19.1825);
         var c2 = new CrdsHorizontal(201.2983, -11.1614);
         Assert.AreEqual(32.7930, Angle.Separation(c1, c2), 1e-4);
     }
 }
示例#11
0
文件: SkyView.cs 项目: t9mike/ADK
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            Select();

            if (SkyMap != null)
            {
                bool shift = (ModifierKeys & Keys.Shift) != Keys.None;

                SkyMap.MousePosition = SkyMap.Projection.Invert(new PointF(e.X, e.Y));

                if (e.Button == MouseButtons.Left && !shift)
                {
                    SkyMap.IsDragging = true;

                    if (SkyMap.LockedObject == null)
                    {
                        if (pOld == Point.Empty)
                        {
                            pOld = new Point(e.X, e.Y);
                        }

                        pNew.X = e.X;
                        pNew.Y = e.Y;
                        double dx = pNew.X - pOld.X;
                        double dy = pNew.Y - pOld.Y;

                        SkyMap.Antialias = Math.Sqrt(dx * dx + dy * dy) < 30;

                        double maxSize = Math.Max(SkyMap.Width, SkyMap.Height);
                        double f       = maxSize / (SkyMap.ViewAngle * 2);

                        if (Math.Abs(SkyMap.Center.Altitude) < 30 || SkyMap.ViewAngle > 80)
                        {
                            SkyMap.Center.Azimuth = (SkyMap.Center.Azimuth - dx / f + 360) % 360;
                        }
                        else
                        {
                            CrdsHorizontal cpNew = SkyMap.Projection.Invert(pNew);
                            CrdsHorizontal cpOld = SkyMap.Projection.Invert(pOld);
                            double         da    = Math.Abs(cpNew.Azimuth - cpOld.Azimuth);
                            da = Math.Abs(da) * Math.Sign(dx);
                            SkyMap.Center.Azimuth -= da;
                            SkyMap.Center.Azimuth %= 360;
                        }

                        SkyMap.Center.Altitude += dy / f;

                        if (SkyMap.Center.Altitude > 90)
                        {
                            SkyMap.Center.Altitude = 90;
                        }
                        if (SkyMap.Center.Altitude < -90)
                        {
                            SkyMap.Center.Altitude = -90;
                        }

                        if (double.IsNaN(SkyMap.Center.Azimuth))
                        {
                            SkyMap.Center.Azimuth = 0;
                        }

                        pOld.X = pNew.X;
                        pOld.Y = pNew.Y;
                    }
                    else
                    {
                        if (Cursor != Cursors.No)
                        {
                            Cursor = Cursors.No;
                        }
                    }
                    Invalidate();
                }
                else
                {
                    SkyMap.IsDragging = false;
                    if (SkyMap.RenderOnMouseMove)
                    {
                        Invalidate();
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Performs a correction of inverse projection.
        /// Checks that horizontal coordinates of a point are correct,
        /// and in case if not correct, applies iterative algorithm for searching correct values.
        /// </summary>
        /// <param name="p">Point to check</param>
        /// <param name="hor">Horizontal coordinates of the point</param>
        /// <returns>Corrected horizontal coordinates</returns>
        private CrdsHorizontal CorrectInverse(PointF p, CrdsHorizontal hor)
        {
            PointF pLeftEdge  = Project(new CrdsHorizontal(Map.Center.Azimuth - 90, hor.Altitude));
            PointF pRightEdge = Project(new CrdsHorizontal(Map.Center.Azimuth + 90, hor.Altitude));

            PointF pEdge;

            if (p.X < Map.Width / 2.0)
            {
                pEdge = pLeftEdge;
            }
            else
            {
                pEdge = pRightEdge;
            }

            Point origin = new Point((int)(Map.Width / 2.0), (int)(Map.Height / 2.0));

            double edgeToCenter = Map.DistanceBetweenPoints(origin, pEdge);

            double currentToCenter = Map.DistanceBetweenPoints(origin, p);

            bool correctionNeeded = Math.Abs(Map.Center.Altitude) == 90 || currentToCenter > edgeToCenter;

            if (correctionNeeded)
            {
                // projected coordinates of a horizontal grid pole (zenith or nadir point)
                PointF pole = Project(new CrdsHorizontal(0, 90 * (Map.Center.Altitude > 0 ? 1 : -1)));

                double angleWhole = 360 - Map.AngleBetweenVectors(pole, pLeftEdge, pRightEdge);

                double angleLeft = Map.AngleBetweenVectors(pole, p, pLeftEdge);

                double angleRight = Map.AngleBetweenVectors(pole, p, pRightEdge);

                int shiftSign = angleLeft < angleRight ? -1 : 1;

                int poleFix = 1;
                if (Map.Center.Altitude == 90 && pole.Y < p.Y)
                {
                    poleFix = -1;
                }
                else if (Map.Center.Altitude == -90 && pole.Y > p.Y)
                {
                    poleFix = -1;
                }

                double poleAngle = Math.Min(angleLeft, angleRight);

                double azimuthShift = poleAngle / angleWhole * 180;

                PointF pCorrected = new PointF(0, 0);

                double distOriginal  = Map.DistanceBetweenPoints(p, pEdge);
                double distCorrected = 0;

                int iterations = 0;

                do
                {
                    hor = new CrdsHorizontal(Angle.To360(Map.Center.Azimuth + shiftSign * 90 + poleFix * shiftSign * azimuthShift), hor.Altitude);

                    // corrected coordinates of a projected point
                    pCorrected = Project(hor);

                    distCorrected = Map.DistanceBetweenPoints(pCorrected, pEdge);

                    if (distCorrected > 0)
                    {
                        azimuthShift *= distOriginal / distCorrected;
                    }
                    iterations++;
                }while (Map.DistanceBetweenPoints(p, pCorrected) > 2 && iterations < 5);
            }

            return(hor);
        }
示例#13
0
 /// <summary>
 /// Map should be renderer on MouseMove only if measure tool is on
 /// </summary>
 public override bool OnMouseMove(CrdsHorizontal mouse, MouseButton mouseButton)
 {
     return(IsMeasureToolOn);
 }
示例#14
0
        public override void Render(IMapContext map)
        {
            double coeff = map.DiagonalCoefficient();

            if (settings.Get <bool>("Ground"))
            {
                const int  POINTS_COUNT = 64;
                PointF[]   hor          = new PointF[POINTS_COUNT];
                double     step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);
                SolidBrush brushGround  = new SolidBrush(map.GetColor(colorGroundNight, colorGroundDay));

                // Bottom part of ground shape

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }
                if (hor[0].X >= 0)
                {
                    hor[0].X = -1;
                }
                if (hor[POINTS_COUNT - 1].X <= map.Width)
                {
                    hor[POINTS_COUNT - 1].X = map.Width + 1;
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    GraphicsPath gp = new GraphicsPath();

                    gp.AddCurve(hor);
                    gp.AddLines(new PointF[]
                    {
                        new PointF(map.Width + 1, map.Height + 1),
                        new PointF(-1, map.Height + 1)
                    });

                    map.Graphics.FillPath(brushGround, gp);
                }
                else if (map.Center.Altitude <= 0)
                {
                    map.Graphics.FillRectangle(brushGround, 0, 0, map.Width, map.Height);
                }

                // Top part of ground shape

                if (map.Center.Altitude > 0)
                {
                    for (int i = 0; i < POINTS_COUNT; i++)
                    {
                        var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle - step * i, 0);
                        hor[i] = map.Project(h);
                    }

                    if (hor.Count(h => !map.IsOutOfScreen(h)) > 2)
                    {
                        GraphicsPath gp = new GraphicsPath();

                        gp.AddCurve(hor);
                        gp.AddLines(new PointF[]
                        {
                            new PointF(map.Width + 1, -1),
                            new PointF(-1, -1),
                        });

                        map.Graphics.FillPath(brushGround, gp);
                    }
                }
            }

            if (map.Schema == ColorSchema.White || (!settings.Get <bool>("Ground") && settings.Get <bool>("HorizonLine")))
            {
                const int POINTS_COUNT = 64;
                PointF[]  hor          = new PointF[POINTS_COUNT];
                double    step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }
                if (hor[0].X >= 0)
                {
                    hor[0].X = -1;
                }
                if (hor[POINTS_COUNT - 1].X <= map.Width)
                {
                    hor[POINTS_COUNT - 1].X = map.Width + 1;
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    Pen penHorizonLine = new Pen(map.GetColor("ColorHorizon"), 2);
                    map.Graphics.DrawCurve(penHorizonLine, hor);
                }
            }

            if (settings.Get <bool>("LabelCardinalDirections"))
            {
                Brush        brushCardinalLabels = new SolidBrush(map.GetColor("ColorCardinalDirections"));
                StringFormat format = new StringFormat()
                {
                    LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center
                };
                for (int i = 0; i < cardinalDirections.Length; i++)
                {
                    var h = new CrdsHorizontal(i * 360 / cardinalDirections.Length, 0);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle * coeff)
                    {
                        PointF p = map.Project(h);
                        p.Y += fontCardinalLabels[i % 2].Height;
                        using (var gp = new GraphicsPath())
                        {
                            map.Graphics.DrawString(Text.Get($"CardinalDirections.{cardinalDirections[i]}"), fontCardinalLabels[i % 2], brushCardinalLabels, p, format);
                        }
                    }
                }
            }
        }
示例#15
0
 public PointF Project(CrdsHorizontal hor)
 {
     return(map.Projection.Project(hor));
 }
示例#16
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (SkyMap != null)
            {
                switch (e.Button)
                {
                case MouseButtons.Left:
                    SkyMap.MouseButton = MouseButton.Left;
                    break;

                case MouseButtons.Right:
                    SkyMap.MouseButton = MouseButton.Right;
                    break;

                default:
                    SkyMap.MouseButton = MouseButton.None;
                    break;
                }

                CrdsHorizontal newMousePosition = SkyMap.Projection.Invert(new PointF(e.X, e.Y));

                if (SkyMap.MouseButton == MouseButton.Left)
                {
                    if (SkyMap.LockedObject == null)
                    {
                        if (pOld == Point.Empty)
                        {
                            pOld = new Point(e.X, e.Y);
                        }

                        pNew.X = e.X;
                        pNew.Y = e.Y;
                        double dx = pNew.X - pOld.X;
                        double dy = pNew.Y - pOld.Y;

                        SkyMap.Antialias = Math.Sqrt(dx * dx + dy * dy) < 30;

                        double maxSize = Math.Max(SkyMap.Width, SkyMap.Height);
                        double f       = maxSize / (SkyMap.ViewAngle * 2);

                        if (Math.Abs(SkyMap.Center.Altitude) < 30 || SkyMap.ViewAngle > 80)
                        {
                            SkyMap.Center.Azimuth = (SkyMap.Center.Azimuth - dx / f + 360) % 360;
                        }
                        else
                        {
                            CrdsHorizontal cpNew = SkyMap.Projection.Invert(pNew);
                            CrdsHorizontal cpOld = SkyMap.Projection.Invert(pOld);
                            double         da    = Math.Abs(cpNew.Azimuth - cpOld.Azimuth);
                            da = Math.Abs(da) * Math.Sign(dx);
                            SkyMap.Center.Azimuth -= da;
                            SkyMap.Center.Azimuth %= 360;
                        }

                        SkyMap.Center.Altitude += dy / f;

                        if (SkyMap.Center.Altitude > 90)
                        {
                            SkyMap.Center.Altitude = 90;
                        }
                        if (SkyMap.Center.Altitude < -90)
                        {
                            SkyMap.Center.Altitude = -90;
                        }

                        if (double.IsNaN(SkyMap.Center.Azimuth))
                        {
                            SkyMap.Center.Azimuth = 0;
                        }

                        pOld.X = pNew.X;
                        pOld.Y = pNew.Y;

                        Invalidate();
                    }
                    else
                    {
                        if (Cursor != Cursors.No)
                        {
                            Invalidate();
                            Cursor = Cursors.No;
                        }
                    }

                    SkyMap.MousePosition = newMousePosition;
                }
                else
                {
                    SkyMap.MousePosition = newMousePosition;
                }
            }
        }
示例#17
0
 /// <summary>
 /// The function is called each time when position of mouse is changed.
 /// Mouse position, converted to horizontal coordinates on map, is passed as parameter.
 /// The function should return true if repaint of map is required,
 /// otherwise it should return false (default behaviour).
 /// </summary>
 /// <param name="mouse">Current mouse position on sky map</param>
 /// <returns>True if repaint of map is required, otherwise false.</returns>
 public virtual bool OnMouseMove(CrdsHorizontal mouse, MouseButton mouseButton)
 {
     return(false);
 }
示例#18
0
 public void GoToPoint(CrdsHorizontal hor, TimeSpan animationDuration)
 {
     GoToPoint(hor, animationDuration, Math.Min(viewAngle, 90));
 }
示例#19
0
 public void GoToPoint(CrdsHorizontal hor, double viewAngleTarget)
 {
     GoToPoint(hor, TimeSpan.Zero, viewAngleTarget);
 }
示例#20
0
 /// <summary>
 /// Creates new instance
 /// </summary>
 public Asteroid()
 {
     Horizontal = new CrdsHorizontal();
 }
示例#21
0
        public override void Render(IMapContext map)
        {
            if (settings.Get <bool>("Ground"))
            {
                const int  POINTS_COUNT = 64;
                PointF[]   hor          = new PointF[POINTS_COUNT];
                double     step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);
                SolidBrush brushGround  = new SolidBrush(map.GetColor(colorGroundNight, colorGroundDay));

                // Bottom part of ground shape

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    GraphicsPath gp = new GraphicsPath();

                    gp.AddCurve(hor);

                    var pts = map.IsInverted ?
                              new PointF[]
                    {
                        new PointF(map.Width + 1, -1),
                        new PointF(-1, -1),
                    } : new PointF[]
                    {
                        new PointF(map.Width + 1, map.Height + 1),
                        new PointF(-1, map.Height + 1)
                    };

                    if (hor.Last().X > map.Width / 2)
                    {
                        gp.AddLines(pts);
                    }
                    else
                    {
                        gp.AddLines(pts.Reverse().ToArray());
                    }

                    map.Graphics.FillPath(brushGround, gp);
                }
                else if (map.Center.Altitude <= 0)
                {
                    map.Graphics.FillRectangle(brushGround, 0, 0, map.Width, map.Height);
                }

                // Top part of ground shape

                if (map.Center.Altitude > 0)
                {
                    for (int i = 0; i < POINTS_COUNT; i++)
                    {
                        var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle - step * i, 0);
                        hor[i] = map.Project(h);
                    }

                    if (hor.Count(h => !map.IsOutOfScreen(h)) > 2)
                    {
                        GraphicsPath gp = new GraphicsPath();

                        gp.AddCurve(hor);
                        gp.AddLines(new PointF[]
                        {
                            new PointF(map.Width + 1, -1),
                            new PointF(-1, -1),
                        });

                        map.Graphics.FillPath(brushGround, gp);
                    }
                }
            }

            if (map.Schema == ColorSchema.White || (!settings.Get <bool>("Ground") && settings.Get <bool>("HorizonLine")))
            {
                const int POINTS_COUNT = 64;
                PointF[]  hor          = new PointF[POINTS_COUNT];
                double    step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    Pen penHorizonLine = new Pen(map.GetColor("ColorHorizon"), 2);
                    map.Graphics.DrawCurve(penHorizonLine, hor);
                }
            }

            if (settings.Get <bool>("LabelCardinalDirections"))
            {
                Brush        brushCardinalLabels = new SolidBrush(map.GetColor("ColorCardinalDirections"));
                StringFormat format = new StringFormat()
                {
                    LineAlignment = StringAlignment.Near, Alignment = StringAlignment.Center
                };
                for (int i = 0; i < cardinalDirections.Length; i++)
                {
                    var h = new CrdsHorizontal(i * 360 / cardinalDirections.Length, 0);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle)
                    {
                        PointF p        = map.Project(h);
                        var    fontBase = settings.Get <Font>("CardinalDirectionsFont");
                        var    font     = new Font(fontBase.FontFamily, fontBase.Size * (i % 2 == 0 ? 1 : 0.75f), fontBase.Style);

                        using (var gp = new GraphicsPath())
                        {
                            map.Graphics.DrawString(Text.Get($"CardinalDirections.{cardinalDirections[i]}"), font, brushCardinalLabels, p, format);
                        }
                    }
                }
            }
        }
示例#22
0
 /// <summary>
 /// Creates new instance
 /// </summary>
 public Comet()
 {
     Horizontal     = new CrdsHorizontal();
     TailHorizontal = new CrdsHorizontal();
 }