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