下面的代码允许我画一 strip 箭头的线:
public sealed class LineArrow : Shape
{
#region X1
public double X1
{
get { return (double)GetValue( X1Property ); }
set { SetValue( X1Property, value ); }
}
// Using a DependencyProperty as the backing store for X1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty X1Property =
DependencyProperty.Register( "X1", typeof( double ), typeof( LineArrow ), new FrameworkPropertyMetadata( 0.0,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure ) );
#endregion
#region Y1
public double Y1
{
get { return (double)GetValue( Y1Property ); }
set { SetValue( Y1Property, value ); }
}
// Using a DependencyProperty as the backing store for Y1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty Y1Property =
DependencyProperty.Register( "Y1", typeof( double ), typeof( LineArrow ), new FrameworkPropertyMetadata(
0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure ) );
#endregion
protected override Geometry DefiningGeometry
{
get
{
var lineStart = new Point( X1, Y1 );
var lineEnd = new Point( this.ActualWidth, this.ActualHeight );
var lineAngle = Math.Atan2( this.ActualHeight, this.ActualWidth );
RotateTransform rotation = new RotateTransform() { Angle = lineAngle * 180 / Math.PI, CenterX = 0.5, CenterY = 0.5 };
TranslateTransform translate = new TranslateTransform( lineEnd.X, lineEnd.Y );
StreamGeometry streamGeometry = new StreamGeometry();
using( StreamGeometryContext geometryContext = streamGeometry.Open() )
{
geometryContext.BeginFigure( lineStart, true, true );
geometryContext.LineTo( lineEnd, true, true );
//left arrow
geometryContext.BeginFigure( lineStart, true, true );
geometryContext.PolyLineTo( new List<Point>()
{
rotation.Transform( new Point( 0, -15 ) ),
rotation.Transform( new Point( -15, 0 ) ),
rotation.Transform( new Point( 0, 15 ) )
}, true, true );
//right arrow
geometryContext.BeginFigure( lineEnd, true, true );
geometryContext.PolyLineTo( new List<Point>()
{
translate.Transform( rotation.Transform( new Point( 0, -15 ) ) ),
translate.Transform( rotation.Transform( new Point( 15,0 ) ) ),
translate.Transform( rotation.Transform( new Point( 0, 15 ) ))
}, true, true );
}
streamGeometry.Freeze();
return streamGeometry;
}
}
}
这是它的行为方式:
如何让箭头在旋转时保持其初始大小 15x15,特别是在接近 180 度或 90 度角时?
最佳答案
让我们考虑一下几何背景。你有一个中心,你有一个箭头。当角度改变时,箭头的长度不应改变。我们刚才描述的形状是什么?是的,你没看错,就是一个圆。现在,圆的属性是什么?它的中心是您用作稳定点的(X1, Y1)点,它的半径是箭头的初始长度。本质上,您打算根据中心、半径和角度找到终点。
假设角度为 alpha。在这种情况下,您正在搜索的 (X2, Y2) 坐标是:
X2 = X1 + radius * cos(alpha)
Y2 = Y1 + radius * sin(alpha)
关于Wpf 自定义 LineArrow 形状旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35600263/