Hur kan jag anpassa pilspetsformen så att den matchar vanliga LaTeX-stilar?

Hur kontrollerar jag formen på mina pilhuvuden? LaTeX ”s TikZ-paket har ett brett utbud av fördefinierade pilspetsstilar, varav några jag vill försöka matcha för Mathematica-figurer som jag importerar till ett LaTeX-dokument:

LaTeX-pilexempel

Men Mathematicas standardpilspetsstil kommer ingenstans nära någon av dessa. Till exempel

Graphics[{Thick, Arrow[{{0, 0}, {-50, 0}}]}] 

ger

Standard Mathematica-pil

Tidigare versioner av Mathematica hade alternativ för att styra pilspetsform, men de verkar vara borta i 8.0.

Hur kan jag få formen på mina Mathematica-pilspetsar så att de matchar LaTeX TikZ-pilspetsstilarna?

Kommentarer

  • Dessutom skalas Mathematica ' pilarna annorlunda från LaTeX-pilspetsar, med en logik som jag kan ' t urskilja. Helst ' vill jag också se till att mina Mathematica-pilar skalas på samma sätt som LaTeX-pilar gör; men det är kanske en separat fråga.
  • Har du tittat på dokumentationen för Arrowheads?
  • Ja, naturligtvis. Ingenting där fick mig nära.
  • @Heike: det ger bara ett exempel för en anpassad pilspets, men ingenting om fördefinierade typer (även om StreamPlot har en miriad av olika inbyggda pilstilar).
  • Se den här frågan – den visar hur man definierar anpassade former, och ställa in absoluta pilspetsstorlekar.

Svar

Här är ett Manipulate för att designa dig själv en 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-grafik

Det är enkelt att lägga till fler kontrollpunkter om behov uppstår.

Grafen för pilspetsen placeras i variabeln h. Observera att den innehåller en Opacity -funktion för bättre synlighet för kontrollpunkterna. Du måste ta bort det om du vill ha ett helt mättat pilhuvud.

Några exempel som skapats med detta Manipulate med:

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-grafik

Koden för pilhuvuden finns i h. Kopiera bara grafiken eller FullForm för att lagra den för senare användning.

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
Ytterligare en kontrollpunkt täcker de vanligaste formerna:

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-grafik

Mathematica-grafik

Kommentarer

  • Fantastiskt! Tack!

Svar

En källa till pilspetsformer är Graph som kommer med en lista över fördefinierade pilspetsformer som du kan ställa in med alternativet EdgeShapeFunction. Du kan få namnen på dessa former genom att göra något liknande

arrowheadNames = GraphElementData["Edge"]; 

Tyvärr är dessa namn i sig själva värdelösa i Arrowheads. Lyckligtvis finns det ett sätt att extrahera Graphics specifikationerna för dessa pilspetsar genom att konvertera en Graph till Graphics använder Show och extraherar Arrowheads -direktiven:

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-grafik

Du kan använda dessa i Arrowheads enligt följande:

grlist = Graphics[{Arrowheads[{{.3, 1, #}}], Arrow[{{0, 0}, {1, 1}}]}] & /@ headlist; GraphicsGrid[Partition[grlist, 5, 5, {1, 1}, ""], Frame -> All] 

Mathematica-grafik

Kommentarer

  • Jag kan ' För att den här koden inte ska fungera längre.
  • Samma här, på Mathematica 10.1, fungerar den här koden inte längre.
  • För detta för att arbeta i Mathematica 10, ersätt GraphicsBox med Graphics: headlist = Flatten[Cases[ Show[Graph[{1 \[DirectedEdge] 2}, EdgeShapeFunction -> #]], Arrowheads[a_] :> Cases[a, _Graphics, Infinity, 1], Infinity, 1] & /@ arrowheadNames];
  • Det finns en felaktig skrivning, Headlist skrivs i början med en liten l ”Headlist” i slutet med versaler L ”HeadList” …
  • I har fixat det, @Phil.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *