貝茲曲線公式理論等等可參考:
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;
}