How can I customize arrowhead shape to match common LaTeX styles?

Here is a Manipulate to design yourself an Arrow:

DynamicModule[{top, baseMid, rightBase, outerMidRight, innerMidRight},
 Manipulate[
  top = {0, 0};
  baseMid = {1, 0} baseMid;
  rightBase = {1, -1} leftBase;
  outerMidRight = {1, -1} outerMidLeft;
  innerMidRight = {1, -1} innerMidLeft;
  h = Graphics[
    {
     Opacity[0.5],
     FilledCurve[
      {
       BSplineCurve[{baseMid, innerMidLeft, leftBase}],
       BSplineCurve[{leftBase, outerMidLeft, top}],
       BSplineCurve[{top, outerMidRight, rightBase}],
       BSplineCurve[{rightBase, innerMidRight, baseMid}]
       }
      ]
     }
    ],
  {{baseMid, {-2, 0}}, Locator},
  {{innerMidLeft, {-2, 0.5}}, Locator},
  {{leftBase, {-2, 1}}, Locator},
  {{outerMidLeft, {-1, 1}}, Locator}
  ]
 ]

Mathematica graphics

It is easy to add more control points if the need arises.

The arrowhead graphics is put in the variable h. Note that it contains an Opacity function for better visibility of the control points. You need to remove that if you want to have a fully saturated arrow head.

Some examples generated with this Manipulate using:

Graphics[
  { Arrowheads[{{Automatic, 1, h /. Opacity[_] :> Sequence[]}}],
    Arrow /@ 
        Table[{{0, 0}, {Sin[t], Cos[t]}}, {t, 0, 2 \[Pi] - 2 \[Pi]/20, 2 \[Pi]/20}]
  }, 
     PlotRangePadding -> 0.2
 ]

Mathematica graphics

The code for the arrow heads can be found in h. Just copy the graphics or the FullForm to store it for later use.

h /. Opacity[_] :> Sequence[] // FullForm

(* ==>
Graphics[{FilledCurve[{BSplineCurve[{{-0.496, 0.}, {-1., 0.48}, {-2,1}}],            
    BSplineCurve[{{-2, 1}, {-0.548, 0.44999999999999996}, {0, 0}}], 
    BSplineCurve[{{0, 0}, {-0.548, -0.44999999999999996}, {-2, -1}}], 
          BSplineCurve[{{-2, -1}, {-1., -0.48}, {-0.496, 0.}}]}]}
]
*)

EDIT
One more control point will cover most common shapes:

DynamicModule[{top, baseMid, outerMidRight, innerMidRight, 
  innerBaseRight, outerBaseRight},
 Manipulate[
  top = {0, 0};
  baseMid = {1, 0} baseMid;
  innerBaseRight = {1, -1} innerBaseLeft;
  outerBaseRight = {1, -1} outerBaseLeft;
  outerMidRight = {1, -1} outerMidLeft;
  innerMidRight = {1, -1} innerMidLeft;
  h = Graphics[
    {
     Opacity[0.5],
     FilledCurve[
      {
       BSplineCurve[{baseMid, innerMidLeft, innerBaseLeft}],
       Line[{innerBaseLeft, outerBaseLeft}],
       BSplineCurve[{outerBaseLeft, outerMidLeft, top}],
       BSplineCurve[{top, outerMidRight, outerBaseRight}],
       Line[{outerBaseRight, innerBaseRight}],
       BSplineCurve[{innerBaseRight, innerMidRight, baseMid}]
       }
      ]
     }
    ],
  {{baseMid, {-2, 0}}, Locator},
  {{innerMidLeft, {-2, 0.5}}, Locator},
  {{innerBaseLeft, {-2, 1}}, Locator},
  {{outerBaseLeft, {-2, 1.1}}, Locator},
  {{outerMidLeft, {-1, 1}}, Locator}
  ]
 ]

Mathematica graphics

Mathematica graphics


One source of arrowhead shapes is Graph which comes with a list of predefined arrowhead shapes that you can set using the option EdgeShapeFunction. You can get the names of these shapes by doing something like

arrowheadNames = GraphElementData["Edge"];

Unfortunately, these names by themselves are useless in Arrowheads. Luckily there is a way to extract the Graphics specifications of these arrowheads by converting a Graph to Graphics using Show and extracting the Arrowheads directives:

headlist = 
  Flatten[Cases[
      Show[Graph[{1 <-> 2}, EdgeShapeFunction -> #]], 
      Arrowheads[a_] :> 
       Cases[a, b_GraphicsBox :> ToExpression[b], Infinity, 1], 
      Infinity, 1] & /@ arrowheadNames];

GraphicsGrid[Partition[headlist, 5, 5, {1, 1}, ""], Frame -> All]

Mathematica graphics

You can use these in Arrowheads as follows:

grlist = Graphics[{Arrowheads[{{.3, 1, #}}], Arrow[{{0, 0}, {1, 1}}]}] & /@ headlist;

GraphicsGrid[Partition[grlist, 5, 5, {1, 1}, ""], Frame -> All]

Mathematica graphics

Tags:

Graphics

Latex