2012-07-11 120 views
2

我正在創建一個可以繪製角度的控件。我有三個依賴對象。如何繪製三點角度的弧線?

  • 半徑:行
  • 由startAngle的長度:從什麼程度我應該開始
  • 角度

下面是截圖有關該計劃目前吸引(紅線是什麼我試圖畫)。

enter image description here

所以我還沒有完成是圓弧。我需要一些幫助來繪製它。這是我的。

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

回答

2

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

注意,這也是一個好主意,打電話給你的AngleChanged處理程序OnApplyTemplate( )這樣,這樣視覺就會在啓動時出現。

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

有一個ArcSegment類可以做到這一點,閱讀文檔。

+1

感謝您對H.B.看起來很混亂的Point和Size屬性,你能否在我的解決方案中提供示例代碼來啓動? – 2012-07-11 21:42:47

+0

不,我不能,那就是爲什麼我說你應該閱讀文檔,這是令人困惑的,我知道。我認爲大小是圓*如果要完全繪製*的邊界框,所以它應該是兩個方向上半徑的兩倍。 – 2012-07-11 21:44:15