2012-12-18 7 views
9

Ho diversi punti, e cerco di disegnare curve Bezier utilizzando il codice qui sottoCome disegnare la curva di Bezier di diversi punti?

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

miei segmenti di Bezier simile a questa

  • 1,2,3 punti - primo segmento
  • 3, 4,5 punti - secondo
  • 5,6,7 .. ..

ma ho avuto questa strana curva (qui è 3 grandi (nodi) e 7 piccola ellisse (è il mio punti)):

enter image description here

+0

Vedo che è naturale avere questa figura, puoi pubblicare un collegamento con la curva desiderata? –

+0

Oppure, forse, vuoi disegnare un singolo segmento con 7 punti di controllo? –

risposta

18

La linea che stai ricevendo è l'unione di tre distinte curve di Bezier - uno per ogni gruppo di tre punti. (Uno per ciascun "segmento Bezier"?)

Se si desidera una curva uniforme, è necessario passare i 9 (o più) punti come una singola raccolta di punti (singolo "segmento Bezier"?), Non come gruppi di tre punti.

Modifica: Apparentemente BezierSegment solo supporta tre punti, quindi non stupisce che questo non funzioni. Anche 'PolyBezierSegment' dà solo una raccolta di segmenti Bezier piuttosto che un singolo Bezier ...

Quindi, poiché WPF non ti dà nulla di utile, ho bussato qualcosa usando la matematica here. Si tratta di una soluzione numerica, ma sembra essere abbastanza performante anche con abbastanza punti per un aspetto gradevole e liscia:

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

Usando questo,

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

Questo è SUPER COOL! Mi ha aiutato molto! Grazie! – Gilad

+0

Approssimazione errata, il tracciato di controllo è stato fatto circolare e disegna un elissoide. Potrebbe essere necessario riconsiderare la matematica approssimativa. – SoLaR

+2

@SoLaR [È impossibile creare una circonferenza usando Beziers] (http://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves). Potrebbe essere necessario riconsiderare come disegnare un cerchio? – Rawling

12

Dal ognuna delle tue curve ha un punto di controllo (un punto che influenza la curva ma non è necessariamente sulla curva), stai usando le curve quadratiche di Bézier.

Se si desidera disegnare due curve quadratiche che condividono un punto finale e si desidera che il giunto appaia liscio, i punti di controllo su ciascun lato dell'endpoint condiviso devono essere allineati con il punto finale. Cioè, i due punti di controllo e il punto finale tra di loro devono trovarsi tutti su una linea retta. Esempio:

quadratics with smooth joints

I solidi dischi neri sono i punti finali. I cerchi vuoti sono i punti di controllo. La linea nera continua è la curva. Le linee tratteggiate mostrano che ciascun punto finale è collineare (su una linea retta con) il punto di controllo su entrambi i lati.