5
$\begingroup$

For a project of mine, I need to plot so-called "anchor lines" (these probably have a better name that I'm simply not aware of), which consist of a single line and smaller lines drawn on one side at a 45 degree angle. Here's my code snippet from a past project in the same vein with an illustration:

LineCounter[n_] := 
 IntegerPart[(n*300)]/Divisors[IntegerPart[n*300]]
 [[Ceiling[Length[Divisors[IntegerPart[n*300]]]/2]]]
GroundLines[length_, centerx_, centery_] := 
    Table[
      Line[{{centerx - length/2 + i - length/LineCounter[length]*Cos[Pi/4], 
                centery - length/LineCounter[length]*Sin[Pi/4]},
            {centerx - length/2 + i, 
                centery}}],
    {i, 0, length, length/LineCounter[length]}]
AnchorLine[length_, centerx_, centery_, angle_] := 
    Rotate[{Line[{{centerx - length/2, centery}, {centerx + length/2, centery}}],
            Thickness[0.0001],
            GroundLines[length, centerx, centery]},
        angle]
Graphics[{
  AnchorLine[3, 0, 0, Pi/3]
  }]

result

This can most likely use some (a lot) of improvement and I will gladly accept any input. What I need is a way to make a similar arc with an arbitrary angle. I've mulled it over for about an hour and I don't see an approach other than bruteforcing my way interatively through angles (more or less the same approach that led to the mess above). This will probably take me at least twice the amount of code and a couple hours to fine-tune for universal use, as I'll probably use it later on, so I need help with a way to simplify this and create a curve version.

Edit: Example, as requested. x and y are coordinates of the starting point, ang1 is angle of the arc, ang2 is angle between the limiting radii and X axis, ang3 is the alignment angle for the small lines (should be the same for all lines, but, you know, Paint...) enter image description here

$\endgroup$
  • $\begingroup$ What do you mean by "a similar arc with an arbitrary angle"? Please respond by editing your question itself, not by a comment. Thanks. $\endgroup$ – bbgodfrey Nov 12 '17 at 18:44
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$ – bbgodfrey Nov 12 '17 at 18:44
  • $\begingroup$ @bbgodfrey Is my drawing ok? $\endgroup$ – bqback Nov 12 '17 at 19:53
3
$\begingroup$

Not too hard to do, tho I changed a few things around so that it jives with the usual syntax for Circle[]:

With[{cent = {2, -1}, r = 2, t1 = π/6, t2 = 3 π/4, (* Circle[] parameters *)
      h = 1/10, (* length of markings *)
      f = -π/6, (* tilt of markings *)
      n = 31 (* number of markings *)}, 
     Graphics[{Circle[cent, r, {t1, t2}], 
               Table[Line[TranslationTransform[cent + r {Cos[t], Sin[t]}] @
                          {{0, 0}, h {Cos[t + f], Sin[t + f]}}],
                     {t, t1, t2, (t2 - t1)/(n - 1)}]}]]

marked arc

$\endgroup$
  • 1
    $\begingroup$ It can also be written Table[Line[TranslationTransform[AngleVector[cent, {r, t}]] @ {{0, 0}, AngleVector[{h, t + f}]}], {t, Subdivide[t1, t2, n - 1]}]. $\endgroup$ – C. E. Nov 13 '17 at 5:26
  • $\begingroup$ I keep forgetting some of these new functions... $\endgroup$ – J. M. will be back soon Nov 13 '17 at 6:00
3
$\begingroup$

Update: It turns out (after seeing the new figure in the question) that I hadn't fully understood what it was about. I will let this answer stay however, since the same approach can be used only now line should be a function that generates a circle segment.


Here's one suggestion. We could start by creating a line made up of as many points as you'd like anchor lines:

line[{x_, y_}, length_, angle_, n_] := 
 Line@Map[{x, y} + # length AngleVector[angle] &, Subdivide[n] ]

l = line[{0, 0}, 10, Pi/4, 10];
Graphics[{l, PointSize[Large], Point @@ l}]

Line example

In the above example, I created a line object of the form Line[{pt1, pt2, pt3, ..., pt10}]. The line has the specified length and is drawn at the specified angle with regards to the x-axis.

To add the anchors, we simply need to generate one line element for each of these points. It can be done like this:

decorate[Line[pts_], length_, angle_] := {
  Line[pts],
  Line[{#, AngleVector[#, {length, angle}]}] & /@ pts
  }

l = line[{0, 0}, 10, Pi/4, 10];
Graphics[{decorate[l, 0.75, 6 Pi/4], PointSize[Large], Point @@ l}]

Anchor line example

It takes a Line[pts] objects, extracts the points and then uses them to create new lines. It then returns the new line along with the old line. When plotting them all together, we get the desired result.

decorate takes both the angle and the length of the anchor lines. The only problem as I see it is that the angle is given with respect to the x-axis rather than the line, which can be fixed by creating a new function like this:

AnchorLine[{x_, y_}, {length_, angle_}, {anchorLength_, anchorAngle_}, n_] := decorate[
  line[{x, y}, length, angle, n], anchorLength, angle + anchorAngle
  ]

Graphics@AnchorLine[{0, 0}, {10, Pi/4}, {0.5, -7 Pi/8}, 10]

Final example

In this function, the angle is given relative to the line, rather than relative to the x-axis.

$\endgroup$
  • $\begingroup$ Thanks, looks much nicer! $\endgroup$ – bqback Nov 12 '17 at 19:56
  • $\begingroup$ Wait, actually when I use it in the program (I run a single graphics in the end after constructing all primitives based on calculations), the beginning coordinates are ignored. I can do AnchorLine[{2535325, 65426256}, {0.35*R, Pi/2}, {0.035*R, 3*Pi/4}, 2], and it's still drawn in the center of the picture. I can even leave the first pair of numbers empty ({,}) and it still works. $\endgroup$ – bqback Nov 12 '17 at 20:21
  • $\begingroup$ @bqback Well, did you set the plot range (PlotRange)? It certainly draws the line in the correct place in the given coordinate system, but if you don't specify PlotRange then it will only show the part of the coordinate system where there is something drawn, which means that the line will always be in the center if that's the only thing that's drawn. $\endgroup$ – C. E. Nov 12 '17 at 20:30
  • $\begingroup$ There are definitely other things present on the plot (the line is in the middle). $\endgroup$ – bqback Nov 12 '17 at 20:45
  • $\begingroup$ @bqback Sorry, I made a mistake. Fixed it now. $\endgroup$ – C. E. Nov 12 '17 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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