2012-12-18 21 views
9

Ich habe einige Punkte, und ich versuche, Bezier-Kurve unter Verwendung von Code unterWie zeichne Bezier-Kurve um mehrere Punkte?

PathFigure pf = new PathFigure(points.From, ps, false); //ps - list of Bezier segments 
    PathFigureCollection pfc = new PathFigureCollection(); 
    pfc.Add(pf); 
    var pge = new PathGeometry(); 
    pge.Figures = pfc; 
    Path p = new Path(); 
    p.Data = pge; 
    p.Stroke = new SolidColorBrush(Color.FromRgb(244, 111, 011)); 

Meine Bezier-Segmente wie folgt aussehen

  • 1,2,3 Punkte zu zeichnen - erste Segment
  • 3, 4,5 Punkte - zweite
  • 5,6,7 .. ..

Aber ich diese seltsame Kurve bekam (hier ist 3 große (Knoten) und 7 kleine Ellipse (ist meine Punkte)):

enter image description here

+0

Ich sehe es ist natürlich, diese Zahl zu haben, können Sie einen Link mit der gewünschten Kurve buchen? –

+0

Oder möchten Sie vielleicht ein einzelnes Segment mit 7 Kontrollpunkten zeichnen? –

Antwort

18

Die Linie Sie bekommen ist die Vereinigung von drei verschiedenen Bezier-Kurven - einer für jede Gruppe von drei Punkten. (Eine für jedes "Bezier-Segment"?)

Wenn Sie eine einzelne glatte Kurve wollen, müssen Sie Ihre 9 (oder mehr) Punkte als eine einzige Sammlung von Punkten (einzelnes "Bezier-Segment"?), Nicht als Gruppen von drei Punkten.

Edit: Anscheinend BezierSegment nur unterstützt drei Punkte, also kein Wunder, dass dies nicht funktioniert. Sogar 'PolyBezierSegment' gibt nur eine Sammlung von Bezier-Segmenten statt einer einzelnen glatten Bezier ...

Also, da WPF nichts nützliches gibt, klopfte ich etwas zusammen mit der Mathematik here. Es ist eine numerische Lösung, aber es scheint ziemlich performant zu sein, auch mit genügend Punkte schön aussehen und glatt:

PolyLineSegment GetBezierApproximation(Point[] controlPoints, int outputSegmentCount) 
{ 
    Point[] points = new Point[outputSegmentCount + 1]; 
    for (int i = 0; i <= outputSegmentCount; i++) 
    { 
     double t = (double)i/outputSegmentCount; 
     points[i] = GetBezierPoint(t, controlPoints, 0, controlPoints.Length); 
    } 
    return new PolyLineSegment(points, true); 
} 

Point GetBezierPoint(double t, Point[] controlPoints, int index, int count) 
{ 
    if (count == 1) 
     return controlPoints[index]; 
    var P0 = GetBezierPoint(t, controlPoints, index, count - 1); 
    var P1 = GetBezierPoint(t, controlPoints, index + 1, count - 1); 
    return new Point((1 - t) * P0.X + t * P1.X, (1 - t) * P0.Y + t * P1.Y); 
} 

diese Verwendung,

private void Grid_Loaded(object sender, RoutedEventArgs e) 
{ 
    Point[] points = new[] { 
      new Point(0, 200), 
      new Point(0, 0), 
      new Point(300, 0), 
      new Point(350, 200), 
      new Point(400, 0) 
     }; 
    var b = GetBezierApproximation(points, 256); 
    PathFigure pf = new PathFigure(b.Points[0], new[] { b }, false); 
    PathFigureCollection pfc = new PathFigureCollection(); 
    pfc.Add(pf); 
    var pge = new PathGeometry(); 
    pge.Figures = pfc; 
    Path p = new Path(); 
    p.Data = pge; 
    p.Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0)); 
    ((Grid)sender).Children.Add(p); 
} 

enter image description here

+0

Das ist SUPER COOL! Hat mir viel geholfen! Vielen Dank! – Gilad

+0

Inkorrekte Approximation, Kontrollpfad wurde zu Kreis und es wird ein Elipsoid gezeichnet. Möglicherweise müssen Sie die Approximationsmathematik überdenken. – SoLaR

+2

@SoLaR [Es ist unmöglich, mit Beziers einen Kreis zu bilden] (http://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves). Sie müssen vielleicht überdenken, wie man einen Kreis zeichnet? – Rawling

12
gibt

Seit Jede Kurve hat einen Kontrollpunkt (einen Punkt, der die Kurve beeinflusst, aber nicht unbedingt auf der Kurve liegt). Sie verwenden quadratische Bézier-Kurven.

Wenn Sie zwei quadratische Kurven zeichnen möchten, die sich einen Endpunkt teilen, und Sie möchten, dass die Verbindung glatt erscheint, müssen die Kontrollpunkte auf jeder Seite des gemeinsamen Endpunkts mit dem Endpunkt kollinear sein. Das heißt, die zwei Kontrollpunkte und der Endpunkt zwischen ihnen müssen alle auf einer geraden Linie liegen. Beispiel:

quadratics with smooth joints

Die festen schwarzen Scheiben sind die Endpunkte. Die hohlen Kreise sind die Kontrollpunkte. Die durchgezogene schwarze Linie ist die Kurve. Die gepunkteten Linien zeigen, dass jeder Endpunkt kollinear (auf einer geraden Linie mit) dem Kontrollpunkt auf jeder Seite ist.

Verwandte Themen