2011-01-08 92 views
0

我首先對不起我的英語,我會試着解釋想要我想做 我需要用wpf繪製一個橢圓,表示一個光環,它的「變形」表示有問題的區域,簡而言之,橢圓可以在運行時間在特定點變形如何在運行時變形橢圓

我想繪製幾個貝塞爾曲線形成一個橢圓,但它不是非常困難(我不知道如何)使點可以被拖動,形成橢圓形的凸起或中空區域。

¿我在自己的英式英語中讓自己清楚了嗎? ¿是否有一個簡單的方法來做到這一點?

在此先感謝

回答

0

我不知道究竟你正在嘗試做的,但我建議讓橢圓的高分辨率版本和跟蹤變形自己。這裏是一個示例程序,讓你開始。

在該演示的XAML很簡單:

<Canvas Name="canvas" Focusable="True" KeyDown="canvas_KeyDown" MouseDown="canvas_MouseDown" MouseMove="canvas_MouseMove" MouseUp="canvas_MouseUp"/> 

和代碼隱藏:

public partial class EllipseDemo : Window 
{ 
    const int resolution = 1000; 
    const double major = 150; 
    const double minor = 100; 
    const double xOrigin = 200; 
    const double yOrigin = 200; 
    const double radius = 10; 
    const double scale = 0.1; 
    const double spread = 10; 
    const double magnitude = 10; 

    Path path; 
    Ellipse controlPoint; 
    LineSegment[] segments; 
    double[] deformation; 
    double[] perturbation; 
    int controlPointIndex; 

    public EllipseDemo() 
    { 
     InitializeComponent(); 

     segments = new LineSegment[resolution]; 
     deformation = new double[resolution]; 
     perturbation = new double[resolution]; 
     for (int i = 0; i < resolution; i++) 
     { 
      var x = i >= resolution/2 ? i - resolution : i; 
      perturbation[i] = magnitude * Math.Exp(-Math.Pow(scale * x, 2)/spread); 
     } 
     path = new Path(); 
     path.Stroke = new SolidColorBrush(Colors.Black); 
     path.StrokeThickness = 5; 
     CalculateEllipse(); 
     canvas.Children.Add(path); 

     controlPoint = new Ellipse(); 
     controlPoint.Stroke = new SolidColorBrush(Colors.Red); 
     controlPoint.Fill = new SolidColorBrush(Colors.Transparent); 
     controlPoint.Width = 2 * radius; 
     controlPoint.Height = 2 * radius; 
     MoveControlPoint(0); 
     canvas.Children.Add(controlPoint); 

     canvas.Focus(); 
    } 

    void CalculateEllipse() 
    { 
     for (int i = 0; i < resolution; i++) 
     { 
      double angle = 2 * Math.PI * i/resolution; 
      double x = xOrigin + Math.Cos(angle) * (major + deformation[i]); 
      double y = yOrigin + Math.Sin(angle) * (minor + deformation[i]); 
      segments[i] = new LineSegment(new Point(x, y), true); 
     } 
     var figure = new PathFigure(segments[0].Point, segments, true); 
     var figures = new PathFigureCollection(); 
     figures.Add(figure); 
     var geometry = new PathGeometry(); 
     geometry.Figures = figures; 
     path.Data = geometry; 
    } 

    void MoveControlPoint(int index) 
    { 
     controlPointIndex = index; 
     Canvas.SetLeft(controlPoint, segments[index].Point.X - radius); 
     Canvas.SetTop(controlPoint, segments[index].Point.Y - radius); 
    } 

    bool mouseDown; 

    void canvas_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     if (Mouse.DirectlyOver != controlPoint) 
      return; 
     mouseDown = true; 
     controlPoint.CaptureMouse(); 
    } 

    void canvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (!mouseDown) 
      return; 
     int index = FindNearestIndex(e.GetPosition(canvas)); 
     MoveControlPoint(index); 
    } 

    void canvas_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     if (!mouseDown) 
      return; 
     controlPoint.ReleaseMouseCapture(); 
     mouseDown = false; 
    } 

    private void canvas_KeyDown(object sender, KeyEventArgs e) 
    { 
     int delta = 0; 
     switch (e.Key) 
     { 
      case Key.Up: 
       delta = 1; 
       break; 
      case Key.Down: 
       delta = -1; 
       break; 
     } 
     if (delta == 0) 
      return; 
     int index = controlPointIndex; 
     for (int i = 0; i < resolution; i++) 
      deformation[(i + index) % resolution] += delta * perturbation[i]; 
     CalculateEllipse(); 
     MoveControlPoint(index); 
    } 

    int FindNearestIndex(Point point) 
    { 
     var min = double.PositiveInfinity; 
     var index = -1; 
     for (int i = 0; i < segments.Length; i++) 
     { 
      var vector = point - segments[i].Point; 
      var distance = vector.LengthSquared; 
      if (distance < min) 
      { 
       index = i; 
       min = distance; 
      } 
     } 
     return index; 
    } 
} 

這工作大多與由線段表示的PathEllipse爲控制點。鼠標可以在橢圓周圍移動控制點,然後使用箭頭鍵添加或移除固定擾動。一切都是硬編碼的,但如果你對數學有好處,那麼它應該可以幫助你開始。

這裏的行動方案:

Ellipse Demo

+0

感謝您的答案延遲對不起,我會嘗試,但我認爲這是我所需要的! – Indy81 2011-01-15 13:29:14