123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- //----------------------------------------------
- // ArrowLineBase.cs (c) 2007 by Charles Petzold
- //----------------------------------------------
- using System.Windows;
- using System.Windows.Media;
- using System.Windows.Shapes;
- namespace DrawGraph
- {
- public enum ArrowEnds
- {
- None = 0,
- Start = 1,
- End = 2,
- Both = 3
- }
- public abstract class ArrowLineBase : Shape
- {
- protected PathGeometry pathgeo;
- protected PathFigure pathfigLine;
- protected PolyLineSegment polysegLine;
- PathFigure pathfigHead1;
- PolyLineSegment polysegHead1;
- PathFigure pathfigHead2;
- PolyLineSegment polysegHead2;
- /// <summary>
- /// Identifies the ArrowAngle dependency property.
- /// </summary>
- public static readonly DependencyProperty ArrowAngleProperty =
- DependencyProperty.Register("ArrowAngle",
- typeof(double), typeof(ArrowLineBase),
- new FrameworkPropertyMetadata(45.0,
- FrameworkPropertyMetadataOptions.AffectsMeasure));
- /// <summary>
- /// Gets or sets the angle between the two sides of the arrowhead.
- /// </summary>
- public double ArrowAngle
- {
- set { SetValue(ArrowAngleProperty, value); }
- get { return (double) GetValue(ArrowAngleProperty); }
- }
- /// <summary>
- /// Identifies the ArrowLength dependency property.
- /// </summary>
- public static readonly DependencyProperty ArrowLengthProperty =
- DependencyProperty.Register("ArrowLength",
- typeof(double), typeof(ArrowLineBase),
- new FrameworkPropertyMetadata(12.0,
- FrameworkPropertyMetadataOptions.AffectsMeasure));
- /// <summary>
- /// Gets or sets the length of the two sides of the arrowhead.
- /// </summary>
- public double ArrowLength
- {
- set { SetValue(ArrowLengthProperty, value); }
- get { return (double) GetValue(ArrowLengthProperty); }
- }
- /// <summary>
- /// Identifies the ArrowEnds dependency property.
- /// </summary>
- public static readonly DependencyProperty ArrowEndsProperty =
- DependencyProperty.Register("ArrowEnds",
- typeof(ArrowEnds), typeof(ArrowLineBase),
- new FrameworkPropertyMetadata(ArrowEnds.End,
- FrameworkPropertyMetadataOptions.AffectsMeasure));
- /// <summary>
- /// Gets or sets the property that determines which ends of the
- /// line have arrows.
- /// </summary>
- public ArrowEnds ArrowEnds
- {
- set { SetValue(ArrowEndsProperty, value); }
- get { return (ArrowEnds) GetValue(ArrowEndsProperty); }
- }
- /// <summary>
- /// Identifies the IsArrowClosed dependency property.
- /// </summary>
- public static readonly DependencyProperty IsArrowClosedProperty =
- DependencyProperty.Register("IsArrowClosed",
- typeof(bool), typeof(ArrowLineBase),
- new FrameworkPropertyMetadata(false,
- FrameworkPropertyMetadataOptions.AffectsMeasure));
- /// <summary>
- /// Gets or sets the property that determines if the arrow head
- /// is closed to resemble a triangle.
- /// </summary>
- public bool IsArrowClosed
- {
- set { SetValue(IsArrowClosedProperty, value); }
- get { return (bool) GetValue(IsArrowClosedProperty); }
- }
- /// <summary>
- /// Initializes a new instance of ArrowLineBase.
- /// </summary>
- public ArrowLineBase()
- {
- pathgeo = new PathGeometry();
- pathfigLine = new PathFigure();
- polysegLine = new PolyLineSegment();
- pathfigLine.Segments.Add(polysegLine);
- pathfigHead1 = new PathFigure();
- polysegHead1 = new PolyLineSegment();
- pathfigHead1.Segments.Add(polysegHead1);
- pathfigHead2 = new PathFigure();
- polysegHead2 = new PolyLineSegment();
- pathfigHead2.Segments.Add(polysegHead2);
- }
- /// <summary>
- /// Gets a value that represents the Geometry of the ArrowLine.
- /// </summary>
- protected override Geometry DefiningGeometry
- {
- get
- {
- int count = polysegLine.Points.Count;
- if (count > 0)
- {
- // Draw the arrow at the start of the line.
- if ((ArrowEnds & ArrowEnds.Start) == ArrowEnds.Start)
- {
- Point pt1 = pathfigLine.StartPoint;
- Point pt2 = polysegLine.Points[0];
- pathgeo.Figures.Add(CalculateArrow(pathfigHead1, pt2, pt1));
- }
- // Draw the arrow at the end of the line.
- if ((ArrowEnds & ArrowEnds.End) == ArrowEnds.End)
- {
- Point pt1 = count == 1 ? pathfigLine.StartPoint : polysegLine.Points[count - 2];
- Point pt2 = polysegLine.Points[count - 1];
- pathgeo.Figures.Add(CalculateArrow(pathfigHead2, pt1, pt2));
- }
- }
- return pathgeo;
- }
- }
- PathFigure CalculateArrow(PathFigure pathfig, Point pt1, Point pt2)
- {
- var matx = new System.Windows.Media.Matrix();
- var vect = pt1 - pt2;
- vect.Normalize();
- vect *= ArrowLength;
- var polyseg = pathfig.Segments[0] as PolyLineSegment;
- polyseg.Points.Clear();
- matx.Rotate(ArrowAngle / 2);
- pathfig.StartPoint = pt2 + vect * matx;
- polyseg.Points.Add(pt2);
- matx.Rotate(-ArrowAngle);
- polyseg.Points.Add(pt2 + vect * matx);
- pathfig.IsClosed = IsArrowClosed;
- return pathfig;
- }
- }
- }
|