基于 EasyX图形库的傻瓜式二阶贝塞尔曲线

#include <easyx.h>
#include <iostream>
#include <graphics.h> // 引用图形库头文件

#include <vector>
#include <math.h>

using namespace std;
#define delayTime 10 //0.01秒刷新一次

unsigned long long befTime=0;

struct POS
{
	float x;
	float y;
};

vector<POS> PointBezier;

void initSupLine(POS begin, POS end, POS control)
{
	//画辅助线
	setlinecolor(GREEN);
	line(begin.x, begin.y, end.x, end.y);
	setlinecolor(RED);
	line(begin.x, begin.y, control.x, control.y);
	line(control.x, control.y, end.x, end.y);
}
//二阶贝塞尔曲线
void doubleBezier(POS begin,POS end,POS control,float* timeSpeed)
{

	//理论贝塞尔
	//动态长度与总长度的比值相等

	float lineControlBegin = sqrt(abs(pow(control.x - begin.x, 2)) + abs(pow(control.y - begin.y, 2)));
	if (*timeSpeed > lineControlBegin) {
		*timeSpeed = lineControlBegin;
		return;
	}

	float lineControlEnd = sqrt(abs(pow(end.x - control.x, 2)) + abs(pow(end.y - control.y, 2)));
	//算出单位向量
	POS initBegin;
	initBegin.x = (control.x - begin.x) / lineControlBegin;
	initBegin.y = (control.y - begin.y) / lineControlBegin;

	POS initEnd;
	initEnd.x = (end.x - control.x) / lineControlEnd;
	initEnd.y = (end.y - control.y) / lineControlEnd;
	
	POS controlBegin;
	POS controlEnd;

	float lineControl = *timeSpeed;
	cout << lineControl << endl;
	float lineControl2 = 0.00f;
	//for (lineControl; lineControl <= lineControlBegin; lineControl+=0.01f)
	//{
		//算出控制点上半部分的坐标点
		controlBegin.x = initBegin.x * lineControl + begin.x;
		controlBegin.y = initBegin.y * lineControl + begin.y;
		//同步比率
		float ratioLength = lineControl / lineControlBegin;

		//算出控制点下半部分的坐标点
		lineControl2 = ratioLength * lineControlEnd;
		controlEnd.x = initEnd.x * lineControl2 + control.x;
		controlEnd.y = initEnd.y * lineControl2 + control.y;
		setlinecolor(YELLOW);
		line(controlBegin.x, controlBegin.y, controlEnd.x, controlEnd.y);

		float lineControlLength = sqrt(abs(pow(controlBegin.x - controlEnd.x, 2)) + abs(pow(controlBegin.y - controlEnd.y, 2)));
		//控制线的单位向量
		POS initControl;
		initControl.x = (controlEnd.x - controlBegin.x) / lineControlLength;
		initControl.y = (controlEnd.y - controlBegin.y) / lineControlLength;
		//控制线的长度
		float controlLineLength = ratioLength * lineControlLength;
		//长度转化成当前线的坐标
		POS controlDraw;
		controlDraw.x = initControl.x * controlLineLength + controlBegin.x;
		controlDraw.y = initControl.y * controlLineLength + controlBegin.y;
		PointBezier.push_back( controlDraw);

}

void drawLine(POS begin, POS end, POS control,float *time)
{
	initSupLine(begin, end, control);
	cout << *time << endl;
	doubleBezier(begin, end, control, time);
	for (vector<POS>::iterator it = PointBezier.begin();it != PointBezier.end();it++)
	{
		POS pointBox = *it;
		putpixel(pointBox.x, pointBox.y, RGB(0, 0, 255));
	}

}


int main()
{
	initgraph(500, 400 , EW_SHOWCONSOLE | EW_DBLCLKS);
	BeginBatchDraw();
	//黑色背景
	setbkcolor(WHITE);
	POS begin = { 90,200 };
	POS end = { 400,200 };
	POS control = { 90,65 };
	float lineControl = 0.00f;
	float* numControl = &lineControl;
	ExMessage m;

	while (1)
	{

		while (peekmessage(&m, -1, true))
		{
			switch (m.message)
			{
			case WM_MOUSEMOVE:

				break;
			case WM_LBUTTONDOWN:
				control.x = m.x;
				control.y = m.y;
				*numControl = 0.00f;
				vector<POS>().swap(PointBezier);
				break;

			default:
				break;
			}
		}

		*numControl += 3.0f;

		drawLine(begin, end, control, numControl);

		FlushBatchDraw();
		/*if (doneDraw) break;*/
		Sleep(delayTime);
		cleardevice();

	}
	EndBatchDraw();

	//saveimage(_T("E:\\test.bmp"));


	//系统暂停
	system("pause");
	closegraph();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值