根据Bezier曲线的定义,画出曲线上密密麻麻的点即可。
运行结果:
源程序:
/**
* Justme0
* 绘制Bezier曲线
*
*/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <cstdlib>
#include "graphics.h"
using namespace std;
// 生成的Bezier曲线由BEZIER_CURVE_POINTS_NUMBER个点组成(粗略说)
const int BEZIER_CURVE_POINTS_NUMBER = 100000;
struct Pt2D {
public:
double x;
double y;
Pt2D():x(0), y(0){}
};
void GetCnk(int n, int *c)
{
// 有更好的算法
for (int k = 0; k <= n; ++k) {
c[k] = 1;
for (int i = n; i >= k + 1; --i) {
c[k] *= i;
}
for (int i = n - k; i >= 2; --i) {
c[k] /= i;
}
}
}
void GetPointPr(int *c, double t, Pt2D *Pt, int ControlN, Pt2D *ControlP)
{
Pt->x = 0; // key!
Pt->y = 0;
double n = ControlN - 1;
for (int k = 0; k < ControlN; ++k) {
double Bernstein = c[k] * pow(t, k) * pow(1 - t, n - k);
Pt->x += ControlP[k].x * Bernstein;
Pt->y += ControlP[k].y * Bernstein;
}
}
void BezierCurve(int m, int ControlN, Pt2D *ControlP)
{
int *C = new int[ControlN]; // 应检测异常
GetCnk(ControlN - 1, C);
moveto(int(ControlP->x), int(ControlP->y));
setcolor(YELLOW);
Pt2D CurvePt;
for (int i = 0; i <= m; ++i) {
GetPointPr(C, (double)i / (double)m, &CurvePt, ControlN, ControlP);
lineto(int(CurvePt.x), int(CurvePt.y));
}
delete []C;
C = NULL;
}
// 给出ControlN个控制点,绘制曲线
void Display(int ControlN, Pt2D ControlP[])
{
initgraph(500, 500);
// 画控制多边形
moveto(int(ControlP->x), int(ControlP->y));
for (int i = 0; i < ControlN; ++i) {
lineto(int(ControlP[i].x), int(ControlP[i].y));
}
// 画Bezier曲线
BezierCurve(BEZIER_CURVE_POINTS_NUMBER, ControlN, ControlP);
Sleep(4000);
closegraph();
}
int main(int argc, char **argv)
{
freopen("cin.txt", "r", stdin);
cout << "请输入点的个数:" << endl;
int ControlN;
cin >> ControlN;
Pt2D *ControlP = new Pt2D[ControlN]; // 应检测异常
cout << "请输入各点坐标:" << endl;
for (int i = 0; i < ControlN; ++i) {
cin >> ControlP[i].x >> ControlP[i].y;
}
Display(ControlN, ControlP);
delete []ControlP;
ControlP = NULL;
return 0;
}
/**cin.txt:
5
400 100
100 100
100 400
400 400
400 250
*/