CG实验4th:Bezier曲线

根据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
*/




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值