-1

I'm making program at school for drawing a Bezier curve (only for n form <1,9>).

For drawing I am using a brute force algorithm from the definition of a curve (for simplicity). I know that De Casteljau would better. When I count points at according parameter t, which is <0.0,1.0> and I also have to set the step for parameterization (the delta t). I call it just step. I have an optional step from 0.1 to 0.05 - I just choose it in GUI.

My main problem is that when I have a step of 0.1 it works fine, but when I have smaller step the curve doesn't reach the last control point. The Bezier curve should start at the first control point and end at the last control point.

Here is my code how I draw it (in C#): vertices is list of control points.

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;
    }
Servy
  • 202,030
  • 26
  • 332
  • 449
user1097772
  • 3,499
  • 15
  • 59
  • 95
  • I'm not sure, because I can't debug your code, but I think the problem lays near rounding your x,y values. I think you can obtain the same x,y for different steps for small step values. The next thing, I'm not sure that using ToInt32 is a good idea. Its description: If value is halfway between two whole numbers, the even number is returned; I think. it is unpredictable behavior. You should make rounding by yourself. – Eugene Petrov Jun 04 '12 at 03:58
  • After examining your code - I agree with Eugene. Check your rounding carefully, I think that even in step=0.5 you are not getting the last control point but since it's just 1 step to the end it looks complete. – G.Y Jun 04 '12 at 04:36
  • But how should I round it then? I thought that ToInt32 is method for conversion to int. But as you say it's probably bad idea to use it there, but I have no clue, what to do instead of it.. – user1097772 Jun 04 '12 at 04:48
  • I solved the problem with rounding by using smaller step. Now I use the step 0.0001 and the curve is nice smooth and ends in start and end points :) And because I have n limited by 9, its also no problem with perfromance... – user1097772 Jun 04 '12 at 18:37

1 Answers1

0

The answer was solved based on the following comment:

I solved the problem with rounding by using smaller step. Now I use the step 0.0001 and the curve is nice smooth and ends in start and end points :) And because I have n limited by 9, its also no problem with perfromance...

-user1097772

Servy
  • 202,030
  • 26
  • 332
  • 449