-1

ベジエ曲線を描くためのプログラムを学校で作成しています (n フォーム <1,9> のみ)。

描画には、曲線の定義からブルート フォース アルゴリズムを使用しています (簡単にするため)。De Casteljauの方がいいのはわかっています。<0.0,1.0> であるパラメーター t でポイントをカウントすると、パラメーター化のステップ (デルタ t) も設定する必要があります。私はそれをただのステップと呼んでいます。0.1 から 0.05 までのオプションのステップがあります。GUI で選択するだけです。

私の主な問題は、ステップが 0.1 の場合は問題なく動作しますが、ステップが小さい場合は曲線が最後の制御点に到達しないことです。ベジエ曲線は、最初の制御点で開始し、最後の制御点で終了する必要があります。

これが私のコードです(C#で):頂点は制御点のリストです。

public void drawBezier(Graphics g, int n, Pen pen) 
   {
       int nuberOfPoints = n + 1; // number of points
       double[] B; //Bernstein polynoms
       double step = ((double)(stepNumericUpDown.Value)) / 100.0; //stepNumericUpDown.Value 
                                                  //could be <5,10> to get step <0.05,0.10>

       List<Point> pointsT = new List<Point>();
       for (double t = 0.0; t <= 1.0; t += step)
       {

           B = new double[nuberOfPoints];
           //count Bernstein polynoms at i position
           for (int i = 0; i < B.Length; i++) B[i] = getBernstein(n, i, t);



           //count points of curve
           Point pointT;
           double x = 0.0;
           double y = 0.0;

           for (int i = 0; i < n + 1; i++)
           {
               x += (vertices[i].X * B[i]); //vertices is List of control Points
               y += (vertices[i].Y * B[i]);
           }
           int xi = Convert.ToInt32(x);
           int yi = Convert.ToInt32(y);
           pointT = new Point(xi, yi);
           pointsT.Add(pointT); //add to list of points of curve
       }

       for (int i = 0; i < pointsT.Count; i++)
       {
           //draw the curve from the points what I've count              
           if ((i - 1) >= 0) g.DrawLine(pen, pointsT[i - 1], pointsT[i]);  //vykreslí čáry             
       }


   }

        }


    /// <summary>
    /// Return bernstein polynom value in n,i,t
    /// </summary>
    /// <param name="n">n</param>
    /// <param name="i">position i</param>
    /// <param name="t">step t</param>
    /// <returns></returns>
    public double getBernstein(int n, int i, double t) 
    {
        double value;
        int nCi = getBinomial(n, i);
        value = nCi * Math.Pow(t, i) * Math.Pow((1 - t), (n - i));
        return value;
    }

    /// <summary>
    /// Count binomial n over k
    /// </summary>
    /// <param name="n">n</param>
    /// <param name="k">k</param>
    /// <returns></returns>
    public int getBinomial(int n, int k)
    {
      int fn = Factorial(n);
      int fk = Factorial(k);
      int fnk = Factorial(n - k);
      return fn / (fk * fnk);
    }

    /// <summary>
    /// Count factorial
    /// </summary>
    /// <param name="factor">argument</param>
    /// <returns></returns>
    public int Factorial(int factor) 
    {

        if (factor > 1)
        {
        return factor * Factorial(--factor);
        }

        return 1;
    }
4

1 に答える 1

0

答えは、次のコメントに基づいて解決されました。

より小さなステップを使用して、丸めの問題を解決しました。今、私はステップ 0.0001 を使用し、曲線は滑らかで開始点と終了点で終わります :) そして、n が 9 で制限されているため、パフォーマンスにも問題はありません...

-user1097772

于 2012-10-23T18:12:55.423 に答える