繁体   English   中英

如何绘制三点角的圆弧?

[英]How to draw the arc of a three point angle?

我正在创建一个可以绘制角度的控件。 我有三个依赖对象。

  • 半径:线的长度
  • StartAngle:我应该从哪个角度开始
  • 角度

这是有关当前正在绘制的程序的屏幕截图(红线是我要绘制的内容)。

在此处输入图片说明

所以我还没有完成的就是弧线。 我需要一些帮助来绘制它。 这就是我所拥有的。

public class AngleControl2 : Control
{
    static AngleControl2()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(AngleControl2), new FrameworkPropertyMetadata(typeof(AngleControl2)));
    }

    public double Angle
    {
        get { return (double)base.GetValue(AngleProperty); }
        set { base.SetValue(AngleProperty, value); }
    }

    public static readonly DependencyProperty AngleProperty =
      DependencyProperty.Register("Angle", typeof(double), typeof(AngleControl2), new PropertyMetadata(90.0, new PropertyChangedCallback(AngleChanged)));

    public double StartAngle
    {
        get { return (double)base.GetValue(StartAngleProperty); }
        set { base.SetValue(StartAngleProperty, value); }
    }

    public static readonly DependencyProperty StartAngleProperty =
      DependencyProperty.Register("StartAngle", typeof(double), typeof(AngleControl2), new PropertyMetadata(0.0, new PropertyChangedCallback(AngleChanged)));

    public double Radius
    {
        get { return (double)base.GetValue(RadiusProperty); }
        set { base.SetValue(RadiusProperty, value); }
    }

    public static readonly DependencyProperty RadiusProperty =
      DependencyProperty.Register("Radius", typeof(double), typeof(AngleControl2), new PropertyMetadata(100.0));

    static void AngleChanged(DependencyObject property, DependencyPropertyChangedEventArgs args)
    {
        AngleControl2 c = (AngleControl2)property;

        Line line1 = c.GetTemplateChild("PART_Line1") as Line;
        Line line2 = c.GetTemplateChild("PART_Line2") as Line;

        if (line1 != null)
        {
            line1.X2 = Math.Cos((c.StartAngle + c.Angle) * (Math.PI / 180)) * c.Radius;
            line1.Y2 = Math.Sin((c.StartAngle + c.Angle) * (Math.PI / 180)) * c.Radius;
        }

        if (line2 != null)
        {
            line2.X2 = Math.Cos(c.StartAngle * (Math.PI / 180)) * c.Radius;
            line2.Y2 = Math.Sin(c.StartAngle * (Math.PI / 180)) * c.Radius;
        }
    }
}

有一个ArcSegment类可以做到这一点,请阅读文档。

使用Path而不是Line会更容易。 例如,如果您要跟踪模板

<Canvas Width="200" Height="200">
    <Path x:Name="PART_Path" Stroke="Green" StrokeThickness="3" Canvas.Left="100" Canvas.Top="100"/>
</Canvas>

然后,您可以在AngleChanged事件中使用以下代码:

Path path = c.GetTemplateChild("PART_Path") as Path;

if (path != null)
{
    Point p = new Point(
        Math.Cos((this.StartAngle + this.Angle) * (Math.PI / 180)) * this.Radius,
        Math.Sin((this.StartAngle - this.Angle) * (Math.PI / 180)) * this.Radius);

    Point q = new Point(
        Math.Cos((this.StartAngle) * (Math.PI / 180)) * this.Radius,
        Math.Sin((this.StartAngle) * (Math.PI / 180)) * this.Radius);

    path.Data = new PathGeometry()
    {
        Figures = new PathFigureCollection()
        {
            new PathFigure()
            {
                StartPoint = new Point(0, 0),
                Segments = new PathSegmentCollection()
                {
                    new LineSegment() { Point = p }
                }
            },
            new PathFigure()
            {
                StartPoint = new Point(0, 0),
                Segments = new PathSegmentCollection()
                {
                    new LineSegment() { Point = q }
                }
            },
            new PathFigure()
            {
                StartPoint = new Point(p.X/3, p.Y/3),
                Segments = new PathSegmentCollection()
                {
                    new ArcSegment()
                    {
                        IsLargeArc = (Math.Abs(this.Angle) % 360) > 180,
                        RotationAngle = Math.Abs(this.Angle) * (Math.PI / 180),
                        SweepDirection = this.Angle < 0 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise,
                        Point = new Point(q.X/ 3, q.Y/ 3),
                        Size = new Size(this.Radius / 3, this.Radius/3)
                    }
                }
            },
        }
    };
}

注意,这样在OnApplyTemplate()中调用AngleChanged处理程序也是一个更好的主意,以便在启动时显示视觉效果。

protected override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    AngleChanged(this, null);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM