DrawArrow
(
DrawingContext oDrawingContext,
Point oArrowTipLocation,
Double dArrowAngle,
Color oColor,
Double dEdgeWidth
)
{
Debug.Assert(oDrawingContext != null);
Debug.Assert(dEdgeWidth > 0);
AssertValid();
// Compute the arrow's dimensions. The width factor is arbitrary and
// was determined experimentally.
const Double WidthFactor = 1.5;
Double dArrowTipX = oArrowTipLocation.X;
Double dArrowTipY = oArrowTipLocation.Y;
Double dArrowWidth = WidthFactor * dEdgeWidth * m_dRelativeArrowSize;
Double dArrowHalfHeight = dArrowWidth / 2.0;
Double dX = dArrowTipX - dArrowWidth;
// Compute the arrow's three points as if the arrow were at an angle of
// zero degrees, then use a rotated transform to adjust for the actual
// specified angle.
Point [] aoPoints = new Point [] {
// Index 0: Arrow tip.
oArrowTipLocation,
// Index 1: Arrow bottom.
new Point(dX, dArrowTipY - dArrowHalfHeight),
// Index 2: Arrow top.
new Point(dX, dArrowTipY + dArrowHalfHeight),
// Index 3: Center of the flat end of the arrow.
//
// Note: The 0.2 is to avoid a gap between the edge endcap and the
// flat end of the arrow, but it sometimes causes the two to
// overlap slightly, and that can show if the edge isn't opaque.
// What is the correct way to get the endcap to merge invisibly
// with the arrow?
new Point(dX + 0.2, dArrowTipY)
};
Matrix oMatrix = WpfGraphicsUtil.GetRotatedMatrix( oArrowTipLocation,
-MathUtil.RadiansToDegrees(dArrowAngle) );
oMatrix.Transform(aoPoints);
PathGeometry oArrow = WpfPathGeometryUtil.GetPathGeometryFromPoints(
aoPoints[0], aoPoints[1], aoPoints[2] );
oDrawingContext.DrawGeometry(GetBrush(oColor), null, oArrow);
return ( aoPoints[3] );
}