如何绘制三点角的圆弧? [英] How to draw the arc of a three point angle?

查看:182
本文介绍了如何绘制三点角的圆弧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • 半径:该行的长度

  • StartAngle:从什么角度开始我应该开始

  • 角度



以下是该程序当前绘制的屏幕截图(红线是我要绘制的内容。)





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

 公共类AngleControl2:控件
{
static AngleControl2()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AngleControl2),new FrameworkPropertyMetadata(typeof(AngleControl2))));
}

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

公共静态只读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); }
}

公共静态只读DependencyProperty StartAngleProperty =
DependencyProperty.Register( StartAngle,typeof(double),typeof(AngleControl2),new PropertyMetadata(0.0,new PropertyChangedCallback( AngleChanged)));

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

公共静态只读DependencyProperty RadiusProperty =
DependencyProperty.Register( Radius,typeof(double),typeof(AngleControl2),new PropertyMetadata(100.0));

静态无效AngleChanged(DependencyObject property,DependencyPropertyChangedEventArgs args)
{
AngleControl2 c =(AngleControl2)property;

Line 1 = c.GetTemplateChild( PART_Line1)作为Line;
行line2 = c.GetTemplateChild( PART_Line2)作为行;

if(line1!= null)
{
line1.X2 = Math.Cos((c.StartAngle + c.Angle)*(Math.PI / 180)) * c。半径;
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。半径
line2.Y2 = Math.Sin(c.StartAngle *(Math.PI / 180))* c.Radius;
}
}
}


解决方案

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

 <画布宽度= 200高度= 200> 
< Path x:Name = PART_Path Stroke =绿色 StrokeThickness = 3 Canvas.Left = 100 Canvas.Top = 100 />
< / Canvas>

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

 路径路径= c.GetTemplateChild( PART_Path)作为路径; 

if(path!= null)
{
Point p = new Point(
Math.Cos((this.StartAngle + this.Angle)* *(数学.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()
{
起点=新点(0,0),
段=新PathSegmentCollection()
{
新LineSegment(){点= p}
}
},
新PathFigure()
{
StartPoint =新点(0,0),
段=新PathSegmentCollection()
{
新LineSegment (){Point = q}
}
},
new PathFigure()
{
StartPoint = new Point(pX / 3,pY / 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(qX / 3,qY / 3),
Size = new Size(this.Radius / 3,this.Radius / 3)
}
}
},
}
};
}

注意,在OnApplyTemplate()中调用AngleChanged处理程序也是一个更好的主意

 受保护的覆盖无效OnApplyTemplate()
{
base.OnApplyTemplate();
AngleChanged(this,null);
}


I'm creating a control where it can draw an angle. I have three dependency objects.

  • Radius: Lenght of the line
  • StartAngle: From what degree should I start
  • Angle

Here's a screenshot about the program currently draws (the red line is what I'm trying to draw).

So what I haven't accomplished yet is the arc. I need some help to draw it. Here's what I have.

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;
        }
    }
}

解决方案

It will be easier to use Path instead of Line. For example, if you have following piece your template

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

Then you can use this code in your AngleChanged event:

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)
                    }
                }
            },
        }
    };
}

Note, it's also a better idea to call your AngleChanged handler in OnApplyTemplate() like this so that the visual will show up at startup.

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

这篇关于如何绘制三点角的圆弧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆