7

Does anyone have an implementation for AnglePath (see AnglePath Documentation and example usage) in Mathematica 10.0?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
pre-kidney
  • 693
  • 3
  • 9

2 Answers2

6

For the first usage, with an input list t of angles, I used:

anglePath[t_?VectorQ] := 
   With[{a = Accumulate[t]}, 
        Join[{{0., 0.}}, Accumulate[Transpose[{Cos[a], Sin[a]}]]]]

For the second usage, with an input matrix of {r,t} pairs, I used:

anglePath[t_?MatrixQ] :=
   With[{a = Accumulate[t[[All, 2]]]}, 
        Join[{{0., 0.}},
             Accumulate[t[[All, 1]]*Transpose[{Cos[a], Sin[a]}]]]
   ]

Borrowing from the blog post:

Graphics[
  {Thick,
   MapIndexed[{ColorData["SandyTerrain", First[#2]/110], Line[#]} &, 
      Partition[anglePath[Table[{r,119.4*Degree},{r,0,1.1,0.01}]],
                2, 1]]},
   Background -> Black]

angle path graphic

KennyColnago
  • 15,209
  • 26
  • 62
3

I managed to figure out how to re-implement AnglePath[], since I needed to do something turtle-related for a friend, and I still do not have access to a computer with version 10.

First, the special cases:

anglePath[steps_] := anglePath[{{0, 0}, 0}, steps]
anglePath[p_?VectorQ, steps_] := anglePath[{p, 0}, steps]
anglePath[alpha0_, steps_] := anglePath[{{0, 0}, alpha0}, steps]
anglePath[{p_?VectorQ, v_?VectorQ}, steps_] :=
          anglePath[{p, Arg[#1 + I #2] & @@ v}, steps]
anglePath[palpha_, steps_?VectorQ] := 
          anglePath[palpha, Transpose[PadLeft[{steps}, {2, Automatic}, 1]]]

I chose to implement the general form through the use of a compiled function; thus, the general case is merely a wrapper for the compiled function apc:

anglePath[{v_?VectorQ, alpha0_}, steps_?MatrixQ] := apc[v, alpha0, steps]

Here's the compiled function that does all the magic:

apc = Compile[{{v0, _Real, 1}, {alpha0, _Real}, {steps, _Real, 2}},
              Module[{alpha = alpha0, z = v0[[1]] + I v0[[2]], pb, r, theta},
                     pb = Internal`Bag[{z}];
                     Scan[({r, theta} = #; Internal`StuffBag[pb,
                           z += r Exp[I (alpha += theta)]]) &, steps];
                     {Re[#], Im[#]} & /@ Internal`BagPart[pb, All]],
              RuntimeOptions -> "Speed"];

In my opinion, the use of the complex number formulation is both mathematically and programmatically elegant. (An opinion I've held ever since reading Zwikker's book.) I did mention the possibility of using Fold[] instead; I'll leave the writing of that version of apc as an exercise for the interested reader.

Here are two examples. The first one is the generation of the so-called "dragon curve":

Graphics[Line[anglePath[KroneckerSymbol[-1, Range[2048]] π/2]]]

dragon curve

(There is an equivalent example in the docs.)

The second example is the use of anglePath[] to generate the spiral of Theodorus:

Graphics[{FaceForm[None], EdgeForm[Black], Polygon[PadRight[#, {3, 2}]] & /@ 
          Partition[anglePath[{{1, 0}, π/2},
                              Prepend[ArcCot[Sqrt[Range[15]]], 0]], 2, 1]}]

spiral of Theodorus, first try

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574