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(); }
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(); }
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(); }