我正在学校制作程序以绘制Bezier曲线(仅适用于n形式< 1,9>)。
对于绘图,我使用了曲线定义中的强力算法(为简单起见)。我知道De Casteljau会更好。当我根据参数t计算点数时,其小于< 0.0,1.0>我还必须设置参数化步骤(delta 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;
}
答案 0 :(得分:0)
答案是根据以下评论解决的:
我通过使用较小的步骤解决了舍入问题。现在我用 步骤0.0001,曲线非常平滑,以开始和结束结束 要点:)因为我有限制9,它也没问题 perfromance ...
-user1097772