Message Boards Message Boards

0
|
2459 Views
|
8 Replies
|
4 Total Likes
View groups...
Share
Share this post:

Plot a 2D figure with circle, triangle, and vectors.

Posted 1 year ago

I want to plot a 2 dimensional figure as shown below:

enter image description here

I tried with the following code snippet, however, the resulting figure does not meet the requirements in some details:

r={1,0};
ars=Arrow[{-#,#}]&/@Table[RotationMatrix[i*Pi/6] . r,{i,0,5}];
tri=Line@Table[RotationMatrix[i*2 Pi/3] . r/2,{i,0,3}];
Graphics[{ars,tri,Circle[{0,0},Norm[r]]}]

Any touch up/enhancements/comments will be highly appreciated.

Regards,
Zhao

POSTED BY: Hongyi Zhao
8 Replies
Posted 1 year ago

These command sequences are relatively long, and I'm not familiar with them, so I need some time to learn them. I will try my best to understand and learn them from scratch.

Thank you again for your comment and advice.

Regards, Zhao

POSTED BY: Hongyi Zhao
Posted 1 year ago

Hi Eric Rimbey,

The label "C" is in a different position, and I have added no styling,

How to put it at the position as shown in my original figure and add some styles?

Thank you for your insightful and wonderful solution, tips, and tricks.

Regards, Zhao

POSTED BY: Hongyi Zhao
Posted 1 year ago

It seems to me that with the several responses you have received you have enough to take a stab at this yourself. You'll need to change how the triangleOuterLabels are positioned, and you'll need to use Style on the individual labels. If you run into a particular obstacle, feel free to post a more specific question.

POSTED BY: Eric Rimbey
Posted 1 year ago

Let's build this up incrementally. We can easily start with the circle:

Graphics[{Circle[]}]

Now we need some "spokes". CirclePoints is a nice function to generate a specified number of points on the unit circle, but they aren't positioned in the way we want them here. We could rotate them, or just generate points ourselves. Looking ahead, we might want to do this for both the spokes and the triangle vertices, so let's write a function (there are many ways to do this, e.g. you might prefer Table):

NormCirclePoints[n_Integer] := NormCirclePoints[n, 1];
NormCirclePoints[n_Integer, radius_] := Most@Array[radius {Cos@#, Sin@#} &, 1 + n, {0, 2 Pi}]

To get spokes, we need to pair each of these points with the circle's center. We also need to wrap Line around the pair. One way to do this is with Outer, and I like making this another function:

CircleSpokes[n_Integer] := Flatten@Outer[Line@*List, {{0, 0}}, NormCirclePoints[n], 1]

Now we can see what we've got so far:

Graphics[{Circle[], CircleSpokes[12]}]

Pretty easy to use what we've got to add the triangle:

Graphics[{Circle[], CircleSpokes[12], Line[NormCirclePoints[3, .5]]}]

Ooops, we need to close the triangle. Could just duplicate the first element at the end, which we can do with Append, but we need to reference the list of points, so at this point, I might start adding in variables:

With[
 {spokes = CircleSpokes[12], vertices = NormCirclePoints[3, .5]},
 Graphics[{Circle[], spokes, Line[Append[vertices, First@vertices]]}]]

Some of our spokes need to be arrows. We can replace certain Lines with Arrows using MapAt:

With[
 {spokes = CircleSpokes[12], vertices = NormCirclePoints[3, .5]},
 With[
  {enhancedSpokes = MapAt[Apply[Arrow], spokes, {{1}, {2}, {4}, {6}}]},
  Graphics[{Circle[], enhancedSpokes, 
    Line[Append[vertices, First@vertices]]}]]]

Now we need to add labels. We want the outer labels aligned with the spokes, so let's "over-specify" them a bit:

Thread[
  Text[
    {x, e, Subscript[\[Sigma], f], d, Null, f, Subscript[\[Sigma], d], Null, Null, Null, Subscript[\[Sigma], e], Null}, 
    NormCirclePoints[12, 1.1]]]

We can add this to our Graphics:

With[
 {spokes = CircleSpokes[12], vertices = NormCirclePoints[3, .5]},
 With[
  {enhancedSpokes = MapAt[Apply[Arrow], spokes, {{1}, {2}, {4}, {6}}],
    spokeLabels = 
    Thread[
     Text[{x, e, Subscript[\[Sigma], f], d, Null, f, 
       Subscript[\[Sigma], d], Null, Null, Null, 
       Subscript[\[Sigma], e], Null}, NormCirclePoints[12, 1.1]]]},
  Graphics[{Circle[], enhancedSpokes, 
    Line[Append[vertices, First@vertices]], spokeLabels}]]]

At this point, I'll just jump to the end. We need to add in the labels for the triangle and add a label for the whole diagram:

With[
 {spokes = CircleSpokes[12], vertices = NormCirclePoints[3, .5]},
 With[
  {enhancedSpokes = MapAt[Apply[Arrow], spokes, {{1}, {2}, {4}, {6}}],
    spokeLabels = 
    Thread[
     Text[{x, e, Subscript[\[Sigma], f], d, Null, f, 
       Subscript[\[Sigma], d], Null, Null, Null, 
       Subscript[\[Sigma], e], Null}, NormCirclePoints[12, 1.1]]],
   triangleInnerLabels = 
    Thread[Text[{a, b, c}, .8 vertices, Background -> White]],
   triangleOuterLabels = 
    Thread[
     Text[{"A", "B", "C"}, RotationTransform[-.1][1.1 vertices], 
      Background -> White]]},
  Labeled[
   Graphics[{Circle[], enhancedSpokes, 
     Line[Append[vertices, First@vertices]], spokeLabels, 
     triangleInnerLabels, triangleOuterLabels}], "(a)"]]]

The label "C" is in a different position, and I have added no styling, so depending on your need for exact fidelity, there may be more work to do here.

POSTED BY: Eric Rimbey
Posted 1 year ago

Note that your CircleSpokes[] is of course expressible in terms of CirclePoints[]:

CircleSpokes[n_Integer, r_ : 1] := Table[Line[{{0, 0}, cp}], {cp, CirclePoints[{r, 0}, n]}]. 

I also note that RegularPolygon[] is a useful primitive here, and one can use e.g.

Directive[FaceForm[], EdgeForm[Black]] 

with it if one only wants its outline.

POSTED BY: J. M.
Posted 1 year ago
r={1,0};
lin=Line[{-#,#}]&/@Table[RotationMatrix[i*Pi/6] . r,{i,2,4,2}];
ars=Arrow[{-#,#}]&/@Table[RotationMatrix[i*Pi/6] . r,{i,1,5,2}];
ars2=Arrow[{#,-#}]&/@Table[RotationMatrix[i*Pi/6] . r,{i,6,6}];
tri=Line@Table[RotationMatrix[i*2 Pi/3] . r/2,{i,0,3}];
txt={
Text["a",RotationMatrix[0Pi/3].r/2,{4,0}],
Text["b",RotationMatrix[2Pi/3].r/2,{-2,2}],
Text["c",RotationMatrix[4Pi/3].r/2,{-2,-2}],
Text["A",RotationMatrix[0Pi/3].r/2,{0,2}],
Text["B",RotationMatrix[2Pi/3].r/2,{-2,-1}],
Text["C",RotationMatrix[4Pi/3].r/2,{-2,1}],
Text[Subscript[\[Sigma],d],RotationMatrix[Pi].r,{2,0}],
Text["f",RotationMatrix[5/6Pi].r,{4,-1}],
Text["d",RotationMatrix[Pi/2].r,{0,-1}],
Text[Subscript[\[Sigma],f],RotationMatrix[Pi/3].r,{0,-1}],
Text["e",RotationMatrix[Pi/6].r,{-1,-1}],
Text["x",RotationMatrix[0Pi].r,{-2,0}],
Text[Subscript[\[Sigma],e],RotationMatrix[-Pi/3].r,{0,2}],
Text["(a)",RotationMatrix[3Pi/2].r,{0,2}]};
Graphics[{lin,ars,ars2,tri,Circle[{0,0},Norm[r]],txt}]
POSTED BY: Bill Nelson
Posted 1 year ago

Hi Bill Nelson,

Although this can also get the final result figure I need, compared with Eric Rimbey's method, this method seems to rely too much on human power and manual input, rather than thinking and solving problems completely based on programming. So its scalability will not be very good.

POSTED BY: Hongyi Zhao

This may be a start:

r = {1, 0};
radius[i_] = RotationMatrix[i*Pi/6] . r;
ars = Arrow[{-#, #}] & /@ Table[radius[i], {i, {0, 1, 3, 5}}];
diamts = 
  Line[{-#, #}] & /@ Table[RotationMatrix[i*Pi/6] . r, {i, {2, 4}}];
tri = Line@Table[RotationMatrix[i*2 Pi/3] . r/2, {i, 0, 3}];
Graphics[{ars, diamts, tri, Circle[{0, 0}, Norm[r]], 
  Text[Style[\!\(TraditionalForm\`\*
StyleBox["d", "TI"]\), Bold], {0, 1}, {0, -2}],
  Text[\!\(TraditionalForm\`
SubscriptBox["\[Sigma]", 
StyleBox["f", "TI"]]\), radius[2], -2 Normalize[radius[2]]]},
 BaseStyle -> {FontSize -> 14}]

I typed the formulas as TeX-style inputs.

POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract