private static void DrawArrowHead(Canvas canvas, PathGeometry linePath, Rect shapeRect, Color color)
{
// Get the intersection point of the imaginary, slightly
// larger rectangle that surrounds the targer shape.
Rect outerRect = new Rect(shapeRect.Left - 10, shapeRect.Top - 10, shapeRect.Width + 20, shapeRect.Height + 20);
RectangleGeometry shapeGeometry = new RectangleGeometry(shapeRect);
Point[] intersectPoints = GetIntersectionPoints(linePath, shapeGeometry);
double innerLeft = intersectPoints[0].X;
double innerTop = intersectPoints[0].Y;
shapeGeometry = new RectangleGeometry(outerRect);
intersectPoints = GetIntersectionPoints(linePath, shapeGeometry);
double outerLeft = intersectPoints[0].X;
double outerTop = intersectPoints[0].Y;
Polygon arrowHead = new Polygon();
arrowHead.Points = new PointCollection();
arrowHead.Points.Add(new Point(innerLeft, innerTop));
arrowHead.Points.Add(new Point(innerLeft + 10, innerTop + 5));
arrowHead.Points.Add(new Point(innerLeft + 10, innerTop - 5));
arrowHead.Points.Add(new Point(innerLeft, innerTop));
arrowHead.Stroke = new SolidColorBrush(color);
arrowHead.Fill = new SolidColorBrush(color);
// The differences between the intersection points on
// the inner and outer shapes gives us the base and
// perpendicular of the right-angled triangle
double baseSize = innerLeft - outerLeft;
double perpSize = innerTop - outerTop;
// Calculate the angle in degrees using ATan
double angle = Math.Atan(perpSize / baseSize) * 180 / Math.PI;
// Rotate another 180 degrees for lines in the 3rd & 4th quadrants
if (baseSize >= 0) angle += 180;
// Apply the rotation to the arrow head
RotateTransform rt = new RotateTransform(angle, innerLeft, innerTop);
arrowHead.RenderTransform = rt;
// Arrow heads are drawn over the lines but
// under the shapes
Canvas.SetZIndex(arrowHead, (int)Layer.Arrow);
canvas.Children.Add(arrowHead);
}
12 years ago
No comments:
Post a Comment