5
$\begingroup$

I'm an avid hunter and shooter. I want to use Mathematica to create a circular dope card that fits within my scope cap. Here's an example:

enter image description here

Here's some sample data of a 6.5 Creedmoor shooting a 140gr bullet out to 500 yards in a 10 mph crosswind.

data = {{"Range", "Elevation", "Windage", "Time"}, {0, "--", "--", 
    0}, {100, -1.8, 0.3, 0.11}, {200, 0, 0.6, 0.25}, {300, 2.4, 0.9, 
    0.36}, {400, 5.2, 1.2, 0.5}, {500, 8.3, 1.5, 0.64}};

Grid[data, Frame -> All]

Mathematica graphics

So, without manually specifying all locations of lines and text boxes, is there:

  1. A way to inscribe a grid of data in a circle?
  2. A way to specify this to a specific size? Say 40mm in diameter.

I would want to create several of these for different rifles, calibers, and loads so automation would be very helpful here.

$\endgroup$
2
  • 1
    $\begingroup$ (pedant) You want to inscribe the grid in the circle; or, circumscribe a circle around the grid. ;) $\endgroup$ Aug 5, 2016 at 2:33
  • $\begingroup$ @J.M. Crap. INSCRIBE! $\endgroup$
    – kale
    Aug 5, 2016 at 2:36

1 Answer 1

3
$\begingroup$

I was hoping someone would have a great quick way to inscribe a grid. Here's my semi-automated way of achieving the same thing.

First, our ballistics input:

data = {{100, -1.8, 0.3, 0.11}, {200, 0.0, 0.6, 0.25}, {300, 2.4, 0.9,
     0.36}, {400, 5.2, 1.2, 0.5}, {500, 8.3, 1.5, 0.64}, {600, 11.9, 
    3.5, 0.79}, {700, 15.6, 4.1, 0.96}, {800, 19.7, 4.8, 1.13}, {900, 
    24.2, 5.6, 1.32}, {1000, 29.2, 6.3, 1.51}, {1100, 34.7, 7.1, 
    1.73}, {1200, 40.7, 7.9, 1.95}};
description = "CT Edge 6.5 Creedmoor 1:8 143 gr 2710 fps";

Now, to build the dope card.

DynamicModule[{cs = 10, len, b = 6.5, dpx, dpy, 
  labels = {"DIST", "ELEV", "WIND", "TIME", "ELEV", "WIND", "TIME", "DIST"},format},
 dpx = Subdivide[b, 0, 3];
 dpy = Subdivide[5.5, -5.5, Min[7, len + 1]];
 format = data;
 format[[All, 1]] = Round[format[[All, 1]]];
 format = 
  format /. 
   r : {d_, e : 0 | 0., w_, t_} :> (Style[#, Bold, Underlined] & /@ r);
 format = 
  format /. 
   r : {d_, e_, w_, t_} :> (Style[#, 12] & /@ {d, PaddedForm[e, {2, 1}], 
       PaddedForm[w, {2, 1}], PaddedForm[t, {3, 2}]});
 len = Length@format;
 Dynamic@Graphics[{
    Circle[{0, 0}, cs],
    Text[Style["Setup", 11, Underlined, Bold], {0, cs - 1}],
    Text[Style["YARDS/MOA", 12, Bold], {0, -cs + 2}],
    Inset[
     Row[{Style[description, 12]}, ImageSize -> 200, 
      Alignment -> {Center, Center}], {0, cs - 2.5}],
    {CapForm["Butt"], Line[posy[#, cs] & /@ dpy]},
    {CapForm["Butt"], Line[{{#, -5.5}, {#, 5.5}} & /@ Subdivide[b, -b, 6]]},
    {Thickness[0.01], CapForm["Butt"], Line[{{0, -5.5}, {0, 5.5}}]},
    Text[#[[1]], {#[[2]] - b/6, Mean[dpy[[;; 2]]]}, {0, 0}] & /@Thread[{labels[[;; 4]], -dpx}],
    Text[#[[1]], {#[[2]] + b/6, Mean[dpy[[;; 2]]]}, {0, 0}] & /@ 
     Thread[{Reverse@labels[[-4 ;;]], dpx}],
    (*First column*)
    With[{fc = Take[format, UpTo[6]]},
     Text[#[[1]], #[[2]], {0, 0}] & /@ 
      Thread[{Flatten[fc], 
        Reverse /@ 
         Tuples[{MovingAverage[Rest[dpy], 2], -dpx - b/6}]}]
     ],
    (*Second column*)
    If[len > 6,
     With[{sc = Take[format, {7, UpTo[12]}]},
      Text[#[[1]], #[[2]], {0, 0}] & /@ 
       Thread[{Flatten[RotateLeft /@ sc], 
         Reverse /@ 
          Tuples[{Take[MovingAverage[Rest[dpy], 2], Length[sc]], 
            Reverse[dpx + b/6]}]}]
      ], Nothing]

    }, PlotRangePadding -> None
   ], Initialization :> (posy[y_, cs_] := {{#, y}, {-#, y}} &@
     Sqrt[(cs^2 - y^2)])
 ]

And our output:

Mathematica graphics

Now, to resize for printing. My scope cap was 1.8".

With[{dia = 1.8}, Rasterize[%, RasterSize -> dia*72*4, ImageSize -> dia*72]]

And the final product:

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.