Como controlo a forma das pontas das minhas flechas? O pacote TikZ do LaTeX tem uma ampla variedade de estilos de ponta de seta predefinidos, alguns dos quais eu gostaria de tentar corresponder às figuras do Mathematica que estou importando para um documento LaTeX:
Mas o estilo de ponta de seta padrão do Mathematica não chega nem perto de nenhum desses. Por exemplo,
Graphics[{Thick, Arrow[{{0, 0}, {-50, 0}}]}]
produz
Versões anteriores do Mathematica tinham opções para controlar o formato da ponta de seta, mas essas parecem ter desaparecido no 8.0.
Como posso fazer com que o formato das pontas de seta do Mathematica corresponda aos estilos de ponta de seta do LaTeX TikZ?
Comentários
Resposta
Aqui está uma Manipulate
para projetar você mesmo um 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} ] ]
É fácil adicionar mais pontos de controle se houver necessidade.
O gráfico da ponta da seta é colocado na variável h
. Observe que ele contém uma função Opacity
para melhor visibilidade dos pontos de controle. Você precisa removê-lo se quiser ter uma ponta de seta totalmente saturada.
Alguns exemplos gerados com este Manipulate
usando:
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 ]
O código para as pontas das setas pode ser encontrado em h
. Basta copiar os gráficos ou FullForm
para armazená-los para uso posterior.
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.}}]}]} ] *)
EDITAR
Mais um ponto de controle cobrirá as formas mais comuns:
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} ] ]
Comentários
- Incrível! Obrigado!
Resposta
Uma fonte de formas de ponta de seta é Graph
que vem com uma lista de formatos de ponta de seta predefinidos que você pode definir usando a opção EdgeShapeFunction
. Você pode obter os nomes dessas formas fazendo algo como
arrowheadNames = GraphElementData["Edge"];
Infelizmente, esses nomes por si só são inúteis em Arrowheads
. Felizmente, há uma maneira de extrair as Graphics
especificações dessas pontas de seta convertendo um Graph
em Graphics
usando Show
e extraindo as Arrowheads
diretivas:
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]
Você pode usá-los em Arrowheads
da seguinte maneira:
grlist = Graphics[{Arrowheads[{{.3, 1, #}}], Arrow[{{0, 0}, {1, 1}}]}] & /@ headlist; GraphicsGrid[Partition[grlist, 5, 5, {1, 1}, ""], Frame -> All]
Comentários
- Eu posso ' não faça este código funcionar mais.
- O mesmo aqui, no Mathematica 10.1, este código não funciona mais.
- Para isso para funcionar no Mathematica 10, substitua
GraphicsBox
porGraphics
:headlist = Flatten[Cases[ Show[Graph[{1 \[DirectedEdge] 2}, EdgeShapeFunction -> #]], Arrowheads[a_] :> Cases[a, _Graphics, Infinity, 1], Infinity, 1] & /@ arrowheadNames];
- Há um erro de digitação, o Headlist é escrito no início com um pequeno l “Headlist” no final com L maiúsculo “HeadList” …
- I consertamos, @Phil.
Arrowheads
?StreamPlot
tenha uma miríade de estilos de seta integrados).