三階貝茲(Bezier )曲線 求滑鼠點(代碼)

貝茲曲線公式理論等等可參考:

https://blog.csdn.net/tianhai110/article/details/2203572

由於三階共有四個點,其中P1及P2是未知,因此先固定一個點,反推P1值後,再用反推的值P1,求另一個點P2。
Get_Beizer3_Value() 先用當前滑鼠點得到P1或者P2。
再透過 Beizer_Curve3() 求得曲線點。
※這邊以四分之一的方式將點的位置做切割,所以P1位置是0.25(1/4),P2是0.75(3/4)。

#define Bizer_P1_P  0.25
#define Bizer_P2_P  0.75
	 Point Get_Beizer3_Value(array<Point>^ point, float t, int X,int Y)
			 {
				 Point Bt, P0, P1, P2, P3; 
				 float t3 = t*t*t, t2 = t*t;
				 float u = (1.0 - t);
				 float u2 = u*u, u3 = u*u*u;
				 P0.X = point[0].X;
				 P1.X = point[1].X;
				 P2.X = point[2].X;
				 P3.X = point[3].X;

				 P0.Y = point[0].Y;
				 P1.Y = point[1].Y;
				 P2.Y = point[2].Y;
				 P3.Y = point[3].Y;

				 Bt.X = X;
				 Bt.Y = Y;

				 if (t == Bizer_P1_P){
					 P1.X = (Bt.X - (t3*P3.X) - (u3*P0.X) - (u * 3 * P2.X*t2)) / (u2*t * 3);
					 P1.Y = (Bt.Y - (t3*P3.Y) - (u3*P0.Y) - (u * 3 * P2.Y*t2)) / (u2*t * 3);
					 return P1;
				 }
				 else if (t == Bizer_P2_P){
					 P2.X = (Bt.X - (t3*P3.X) - (u3*P0.X) - (u2*t * 3 * P1.X)) / (u * 3 * t2);
					 P2.Y = (Bt.Y - (t3*P3.Y) - (u3*P0.Y) - (u2*t * 3 * P1.Y)) / (u * 3 * t2);
					 return P2;
				 }

				 return Bt;
			 }
 void Beizer_Curve3(array<Point>^ point, int times)
			 {
				 int Bx[4], By[4];
				 float t1 = 1.0 / times;
				 float t = t1;
				 float X, Y;
				 int last_X = point[0].X, last_Y = point[0].Y;
				 float uuu = (1.0f - t)* (1.0f - t) *(1.0f - t);
				 float uu = (1.0f - t)* (1.0f - t);
				 float tt = t*t;
				 float ttt = t*t*t;
				 for (int i = 0; i < 4; i++){
					 Bx[i] = point[i].X;
					 By[i] = point[i].Y;
				 }

				 GammaGraphics->Clear(Color::White);
				 draw_Grids(Color::Gray);
				 Pen^ GPen;
				 if (radioButton_R->Checked){
					 GPen = gcnew Pen(Color::Red);
				 }
				 else if (radioButton_G->Checked){
					 GPen = gcnew Pen(Color::Green);
				 }
				 else if (radioButton_B->Checked){
					 GPen = gcnew Pen(Color::Blue);
				 }
				 else {
					 GPen = gcnew Pen(Color::Black);
				 }

				 for (int i = 1; i <= times; i++){

					 X = Bx[0] * uuu + 3.0*Bx[1] * t*uu + 3.0*Bx[2] * tt*(1.0 - t) + Bx[3] * ttt;
					 Y = By[0] * uuu + 3.0*By[1] * t*uu + 3.0*By[2] * tt*(1.0 - t) + By[3] * ttt;
					 t += t1;
					 uuu = (1.0f - t)* (1.0f - t) *(1.0f - t);
					 uu = (1.0f - t)* (1.0f - t);
					 tt = t*t;
					 ttt = t*t*t;

					 if (X < 0)
						 X = 0;
					 else if (X>255)
						 X = 255;
					 else if (Y < 0)
						 Y = 0;
					 else if (Y > 255)
						 Y = 255;

					 GammaGraphics->DrawLine(GPen, last_X, 255-last_Y, (int)X, 255-(int)Y);


					 for (int j = (int)X; j < 256; j++){
						 if ((int)X == j){
							 GammaTemp[j] = Y;
							 break;
						 }
					 }


					 last_Y = Y;
					 last_X = X;

					 if (i == (int)(times * Bizer_P1_P) || i == (int)(times * Bizer_P2_P)){
						 Pen^ blackPen = gcnew Pen(Color::DarkBlue, 5.0f);
						 GammaGraphics->DrawRectangle(blackPen, (int)X,(int)(255-Y), 1, 1);
						 if (i == (int)(times * Bizer_P1_P)){
							 line_point1.X = X;
							 line_point1.Y = Y;
							 if (radioButton_R->Checked){
								 CtrlR_Point1.X = X;
								 CtrlR_Point1.Y = 255- Y;
							 }
							 else if (radioButton_G->Checked){
								 CtrlG_Point1.X = X;
								 CtrlG_Point1.Y = 255- Y;
							 }
							 else if (radioButton_B->Checked){
								 CtrlB_Point1.X = X;
								 CtrlB_Point1.Y = 255-Y;
							 }
							 else {
								 CtrlRGB_Point1.X = X;
								 CtrlRGB_Point1.Y = 255- Y;
							 }
						 }
						 else if (i == (int)(times * Bizer_P2_P)){
							 line_point2.X = X;
							 line_point2.Y = Y;
							 if (radioButton_R->Checked){
								 CtrlR_Point2.X = X;
								 CtrlR_Point2.Y = 255-Y;
							 }
							 else if (radioButton_G->Checked){
								 CtrlG_Point2.X = X;
								 CtrlG_Point2.Y = 255-Y;
							 }
							 else if (radioButton_B->Checked){
								 CtrlB_Point2.X = X;
								 CtrlB_Point2.Y = 255-Y;
							 }
							 else {
								 CtrlRGB_Point2.X = X;
								 CtrlRGB_Point2.Y = 255-Y;
							 }
						 }
					 }

				 }
				 pictureBox1->Image = GammaBitmap;

			 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值