Example #1
0
        private static void Draw(ReticleDefinition reticle, string baseName, TrajectoryPoint[] trajectory)
        {
            const double svgWidth  = 10;
            double       svgHeight = Math.Round(reticle.Size.Y / reticle.Size.X * svgWidth, 2);

            var canvas     = SvgCanvasFactory.Create("reticle", $"{svgWidth}in", $"{svgHeight}in");
            var controller = new ReticleDrawController(reticle, canvas);

            controller.DrawReticle();
            controller.DrawBulletDropCompensator(trajectory, DistanceUnit.Yard.New(100), false, DistanceUnit.Yard, "black");
            var svg = SvgCanvasFactory.ToSvg(canvas);

            const int pngWidth  = 1024;
            int       pngHeight = (int)((reticle.Size.Y / reticle.Size.X) * pngWidth);

            XmlDocument xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(svg);
            var      svgDocument = SvgDocument.Open(xmlDocument);
            var      bm          = svgDocument.Draw(pngWidth, pngHeight);
            var      bm1         = new Bitmap(pngWidth, pngHeight);
            Graphics g           = Graphics.FromImage(bm1);

            g.FillRectangle(Brushes.White, 0, 0, pngWidth, pngHeight);
            g.DrawImage(bm, 0, 0);
            bm1.Save($"{baseName}.png", ImageFormat.Png);
            xmlDocument.Save($"{baseName}.svg");

            xmlDocument = new XmlDocument();
            BallisticXmlSerializer serializer = new BallisticXmlSerializer(xmlDocument);

            xmlDocument.AppendChild(serializer.Serialize(reticle));
            xmlDocument.Save($"{baseName}.reticle");
        }
        public void ReticleElement_Rectangle(
            double sx0, double sy0, double sx1, double sy1, double sw, string color, bool fill,
            float dx0, float dy0, float dx1, float dy1, float dw)
        {
            var canvas  = CreateMockCanvas();
            var reticle = CreateReticle();

            reticle.Elements.Add(new ReticleRectangle()
            {
                TopLeft   = new ReticlePosition(sx0, sy0, AngularUnit.Mil),
                Size      = new ReticlePosition(sx1, sy1, AngularUnit.Mil),
                LineWidth = AngularUnit.Mil.New(sw),
                Color     = color,
                Fill      = fill,
            });

            canvas.Setup(canvas => canvas.Rectangle(
                             It.Is <float>(f => Approximately(f, dx0)),
                             It.Is <float>(f => Approximately(f, dy0)),
                             It.Is <float>(f => Approximately(f, dx1)),
                             It.Is <float>(f => Approximately(f, dy1)),
                             It.Is <float>(f => Approximately(f, dw)),
                             It.Is <bool>(b => b == fill),
                             It.Is <string>(s => s == color))).Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawReticle();
            canvas.Verify();
        }
Example #3
0
        private static void Draw(ReticleDefinition reticle, string baseName)
        {
            var canvas     = SvgCanvasFactory.Create("reticle", "2in", "2in");
            var controller = new ReticleDrawController(reticle, canvas);

            controller.DrawReticle();
            var svg = SvgCanvasFactory.ToSvg(canvas);

            XmlDocument xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(svg);
            var      svgDocument = SvgDocument.Open(xmlDocument);
            var      bm          = svgDocument.Draw(1024, 1024);
            var      bm1         = new Bitmap(1024, 1024);
            Graphics g           = Graphics.FromImage(bm1);

            g.FillRectangle(Brushes.White, 0, 0, 1024, 1024);
            g.DrawImage(bm, 0, 0);
            bm1.Save($"{baseName}.png", ImageFormat.Png);
            xmlDocument.Save($"{baseName}.svg");

            xmlDocument = new XmlDocument();
            BallisticXmlSerializer serializer = new BallisticXmlSerializer(xmlDocument);

            xmlDocument.AppendChild(serializer.Serialize(reticle));
            xmlDocument.Save($"{baseName}.reticle");

            xmlDocument = new XmlDocument();
            xmlDocument.Load($"{baseName}.reticle");
            BallisticXmlDeserializer deserializer = new BallisticXmlDeserializer();

            _ = deserializer.Deserialize <ReticleDefinition>(xmlDocument.DocumentElement);
        }
        public void Reticle_DrawShot()
        {
            var canvas     = CreateMockCanvas();
            var reticle    = CreateReticle();
            var trajectory = TableLoader.FromResource("g1_wind");

            // How constants calculated:
            //     Reticle: 10x10mil
            //     Canvas: 10000x1000 pixels
            //     Center of Target @ 250ft (see trajectory -> -3.2moa drop (0.95068 mil), 2.6moa windage (0.75828 mil))
            //     Map center to target: mil to pixel y: 950, x: 758 against zero @ 5000x5000
            //     Linear size of the target = atan(8 inches / 250 yards) = 0.905414549 mil => 905 pixels
            //     c1 = center - size / 2, c2 = center + size / 2

            canvas.Setup(canva => canva.Rectangle(
                             It.Is <float>(f => Approximately(f, 5305, 5)),
                             It.Is <float>(f => Approximately(f, 5497, 5)),
                             It.Is <float>(f => Approximately(f, 6210, 5)),
                             It.Is <float>(f => Approximately(f, 6403, 5)),
                             It.Is <float>(f => Approximately(f, 1, 0.1f)),
                             It.Is <bool>(b => !b),
                             It.Is <string>(s => s == "zecolor"))).Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawTarget(trajectory.Trajectory, DistanceUnit.Inch.New(8), DistanceUnit.Yard.New(250), "zecolor");

            canvas.Verify();
        }
        public void ReticleElement_Line_ZeroOffCenter(
            double sx0, double sy0, double sx1, double sy1, double sw, string color,
            float dx0, float dy0, float dx1, float dy1, float dw)
        {
            var canvas  = CreateMockCanvas();
            var reticle = CreateReticle(10, 4);

            reticle.Elements.Add(new ReticleLine()
            {
                Start     = new ReticlePosition(sx0, sy0, AngularUnit.Mil),
                End       = new ReticlePosition(sx1, sy1, AngularUnit.Mil),
                LineWidth = AngularUnit.Mil.New(sw),
                Color     = color,
            });

            canvas.Setup(canvas => canvas.Line(
                             It.Is <float>(f => Approximately(f, dx0)),
                             It.Is <float>(f => Approximately(f, dy0)),
                             It.Is <float>(f => Approximately(f, dx1)),
                             It.Is <float>(f => Approximately(f, dy1)),
                             It.Is <float>(f => Approximately(f, dw)),
                             It.Is <string>(s => s == color))).Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawReticle();
            canvas.Verify();
        }
        public void ReticleElement_Text(
            double sx0, double sy0, double sh, string text, string color,
            float dx0, float dy0, float dh)
        {
            var canvas  = CreateMockCanvas();
            var reticle = CreateReticle();

            reticle.Elements.Add(new ReticleText()
            {
                Position   = new ReticlePosition(sx0, sy0, AngularUnit.Mil),
                TextHeight = AngularUnit.Mil.New(sh),
                Text       = text,
                Color      = color,
            });

            canvas.Setup(canvas => canvas.Text(
                             It.Is <float>(f => Approximately(f, dx0)),
                             It.Is <float>(f => Approximately(f, dy0)),
                             It.Is <float>(f => Approximately(f, dh)),
                             It.Is <string>(s => s == text),
                             It.Is <string>(s => s == color))).Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawReticle();
            canvas.Verify();
        }
Example #7
0
        private static void DrawGraphics(ReticleDefinition reticle, string baseName)
        {
            var bm1    = new Bitmap(1024, 1024);
            var canvas = GraphicsCanvas.FromImage(bm1, Color.White);

            canvas.Clear();
            var controller = new ReticleDrawController(reticle, canvas);

            controller.DrawReticle();
            bm1.Save($"{baseName}-a.png", ImageFormat.Png);
        }
        internal void UpdateImage()
        {
            if (Reticle.Size == null)
            {
                picturePreview.Image = null;
                return;
            }

            AppForm.CalculateReticleImageSize(picturePreview.Size.Width, picturePreview.Size.Height,
                                              Reticle.Size.X, Reticle.Size.Y, out int imageX, out int imageY);

            Bitmap                bm         = new Bitmap(imageX, imageY);
            GraphicsCanvas        canvas     = GraphicsCanvas.FromImage(bm, Color.White);
            ReticleDrawController controller = new ReticleDrawController(Reticle, canvas);

            canvas.Clear();
            controller.DrawElement(Path);
            picturePreview.Image = bm;
        }
        public void BDC_LongRange()
        {
            var canvas     = CreateMockCanvas();
            var reticle    = CreateReticle();
            var trajectory = TableLoader.FromResource("g1_nowind");

            //we need detailed trajectory to calculate BDC
            var calc = new TrajectoryCalculator();

            trajectory.ShotParameters.SightAngle      = calc.SightAngle(trajectory.Ammunition, trajectory.Rifle, trajectory.Atmosphere);
            trajectory.ShotParameters.Step            = DistanceUnit.Yard.New(10);
            trajectory.ShotParameters.MaximumDistance = DistanceUnit.Yard.New(500);
            var trajectory1 = calc.Calculate(trajectory.Ammunition, trajectory.Rifle, trajectory.Atmosphere, trajectory.ShotParameters, new[] { trajectory.Wind });

            reticle.BulletDropCompensator.Add(new ReticleBulletDropCompensatorPoint()
            {
                Position   = new ReticlePosition(AngularUnit.Mil.New(0), AngularUnit.Mil.New(-0.5)),
                TextHeight = AngularUnit.Mil.New(0.5),
                TextOffset = AngularUnit.Mil.New(0),
            });

            reticle.BulletDropCompensator.Add(new ReticleBulletDropCompensatorPoint()
            {
                Position   = new ReticlePosition(AngularUnit.Mil.New(0), AngularUnit.Mil.New(-1)),
                TextHeight = AngularUnit.Mil.New(0.5),
                TextOffset = AngularUnit.Mil.New(1),
            });

            reticle.BulletDropCompensator.Add(new ReticleBulletDropCompensatorPoint()
            {
                Position   = new ReticlePosition(AngularUnit.Mil.New(0), AngularUnit.Mil.New(-2)),
                TextHeight = AngularUnit.Mil.New(0.5),
                TextOffset = AngularUnit.Mil.New(-1),
            });

            canvas.Setup(canvas => canvas.Text(
                             It.Is <float>(f => Approximately(f, 5000)),                   //x == center
                             It.Is <float>(f => Approximately(f, 5750)),                   //x - 0.5mil(dot) + 0.5mil(text height) / 2
                             It.Is <float>(f => Approximately(f, 500)),
                             It.Is <string>(s => Approximately(float.Parse(s), 195, 10f)), //~195 yards on the trajectory of test
                             It.Is <string>(s => s == "black"))).Verifiable();

            canvas.Setup(canvas => canvas.Text(
                             It.Is <float>(f => Approximately(f, 6000)),                   //x == center + 1 mil
                             It.Is <float>(f => Approximately(f, 6250)),                   //x - 1mil(dot) + 0.5mil(text height) / 2
                             It.Is <float>(f => Approximately(f, 500)),
                             It.Is <string>(s => Approximately(float.Parse(s), 257, 10f)), //~257 yards on the trajectory of test
                             It.Is <string>(s => s == "black"))).Verifiable();

            canvas.Setup(canvas => canvas.Text(
                             It.Is <float>(f => Approximately(f, 4000)),                   //x == center - 1 mil
                             It.Is <float>(f => Approximately(f, 7250)),                   //x - 2mil(dot) + 0.5mil(text height) / 2
                             It.Is <float>(f => Approximately(f, 500)),
                             It.Is <string>(s => Approximately(float.Parse(s), 356, 10f)), //~356 yards on the trajectory of test
                             It.Is <string>(s => s == "black"))).Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawBulletDropCompensator(trajectory1, trajectory.Rifle.Zero.Distance, false, DistanceUnit.Yard, "black");

            canvas.Verify();
        }
        public void ReticleElement_Path()
        {
            var canvas  = CreateMockCanvas();
            var reticle = CreateReticle();

            var reticlePath = new ReticlePath()
            {
                Color = "red",
                Fill  = true,
            };

            reticlePath.Elements.Add(new ReticlePathElementMoveTo()
            {
                Position = new ReticlePosition(-2.5, 0, AngularUnit.Mil),
            });

            reticlePath.Elements.Add(new ReticlePathElementLineTo()
            {
                Position = new ReticlePosition(0, 1, AngularUnit.Mil),
            });

            reticlePath.Elements.Add(new ReticlePathElementLineTo()
            {
                Position = new ReticlePosition(2.5, 0, AngularUnit.Mil),
            });

            reticlePath.Elements.Add(new ReticlePathElementArc()
            {
                Position           = new ReticlePosition(-2.5, 0, AngularUnit.Mil),
                ClockwiseDirection = false,
                MajorArc           = true,
                Radius             = AngularUnit.Mil.New(2.5)
            });

            reticle.Elements.Add(reticlePath);

            int order = 0;

            var canvasPath = new Mock <IReticleCanvasPath>();

            canvasPath.Setup(
                path => path.MoveTo(
                    It.Is <float>(f => Approximately(f, 2500)),
                    It.Is <float>(f => Approximately(f, 5000))
                    ))
            .Callback(() => (order++).Should().Be(1, "Order of adding path items into path failed"))
            .Verifiable();

            canvasPath.Setup(
                path => path.LineTo(
                    It.Is <float>(f => Approximately(f, 5000)),
                    It.Is <float>(f => Approximately(f, 4000))
                    ))
            .Callback(() => (order++).Should().Be(2, "Order of adding path items into path failed"))
            .Verifiable();

            canvasPath.Setup(
                path => path.LineTo(
                    It.Is <float>(f => Approximately(f, 7500)),
                    It.Is <float>(f => Approximately(f, 5000))
                    ))
            .Callback(() => (order++).Should().Be(3, "Order of adding path items into path failed"))
            .Verifiable();

            canvasPath.Setup(
                path => path.Arc(
                    It.Is <float>(f => Approximately(f, 2500)),
                    It.Is <float>(f => Approximately(f, 2500)),
                    It.Is <float>(f => Approximately(f, 5000)),
                    It.Is <bool>(f => f),
                    It.Is <bool>(f => !f)
                    ))
            .Callback(() => (order++).Should().Be(4, "Order of adding path items into path failed"))
            .Verifiable();

            canvas.Setup(
                canvas => canvas.CreatePath())
            .Returns(canvasPath.Object)
            .Callback(() => (order++).Should().Be(0, "Creating a patch must be first action"))
            .Verifiable();

            canvas.Setup(
                canvas => canvas.Path(
                    It.Is <IReticleCanvasPath>(path => path == canvasPath.Object),
                    It.Is <float>(f => Approximately(f, 1)),
                    It.Is <bool>(f => f),
                    It.Is <string>(s => s == "red")))
            .Callback(() => (order++).Should().Be(5, "Drawing path must be the last action"))
            .Verifiable();

            ReticleDrawController controller = new ReticleDrawController(reticle, canvas.Object);

            controller.DrawReticle();
            canvas.Verify();
            canvasPath.Verify();
        }