Wpf 自定义 LineArrow 形状旋转

标签 wpf rotation shapes

下面的代码允许我画一 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;              
        }
    }
}

这是它的行为方式:

enter image description here

如何让箭头在旋转时保持其初始大小 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/

相关文章:

javascript - 三个 JS 创建自定义形状几何体

android - 如何设置 TabLayout ta 的圆形波纹形状?

c# - WPF 中的 CommandLink

c# - 即使在外部终止时,也使 WPF 应用程序有机会清理其资源

java - 在我的 Android 项目中,跨旋转保存数据似乎不起作用

javascript - 带有 JQuery 修复的内容旋转器 : how to scroll each thumbnail and not set?

java - 绘制矩形

c# - 调用命令方法时属性为空

c# - WPF:一些 Expression Blend 主题导致 Combobox 绑定(bind)/显示中的错误

javascript - Canvas 从底部中心图像 Angular 旋转?