9

いくつかのポイントがあり、以下のコードを使用してベジェ曲線を描画しようとしています

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

私のベジェセグメントは次のようになります

  • 1,2,3ポイント-最初のセグメント
  • 3,4,5ポイント-秒
  • 5,6,7...。

しかし、私はこの奇妙な曲線を手に入れました(ここに3つの大きな(ノード)と7つの小さな楕円(私のポイント)があります):

ここに画像の説明を入力してください

4

2 に答える 2

23

あなたが得ている線は、3つの異なるベジェ曲線の和集合です-3つのポイントの各グループに1つです。(「ベジェセグメント」ごとに1つ?)

単一の滑らかな曲線が必要な場合は、3つのポイントのグループとしてではなく、9つ(またはそれ以上)のポイントを単一のポイントのコレクション(単一の「ベジェセグメント」?)として渡す必要があります。

編集:どうやら3つのポイントBezierSegmentしかサポートしていないので、これが機能しないのも不思議ではありません。'PolyBezierSegment'でさえ、単一の滑らかなベジェではなく、ベジェセグメントのコレクションを提供します...

WPFは有用なものを何も提供しないので、ここで数学を使用して何かを一緒にノックしました。これは数値的な解決策ですが、見栄えが良く滑らかに見えるのに十分なポイントがあっても、かなりパフォーマンスが高いようです。

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

これを使って、

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

与える

ここに画像の説明を入力してください

于 2012-12-19T08:14:54.050 に答える
15

各曲線には1つの制御点(曲線に影響を与えるが、必ずしも曲線上にあるとは限らない点)があるため、2次ベジェ曲線を使用しています。

端点を共有する2つの二次曲線を描画し、ジョイントを滑らかに表示する場合は、共有端点の両側の制御点が端点と同一線上にある必要があります。つまり、2つのコントロールポイントとそれらの間のエンドポイントはすべて直線上にある必要があります。例:

滑らかな関節を持つ二次方程式

黒一色のディスクがエンドポイントです。白丸はコントロールポイントです。黒の実線が曲線です。点線は、各端点が両側の制御点と同一線上にある(直線上にある)ことを示しています。

于 2012-12-19T09:08:39.110 に答える