绘制贝塞尔Bezier曲线

// TrainingTools.cpp : 定义控制台应用程序的入口点。
//
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int WW_MAX_MARK_COUNT = 40; //最大40个控制点
int mark_count =4;
int conner_pt_index =-1;
CvPoint3D32f Control_pts[WW_MAX_MARK_COUNT];
IplImage *image = 0 ; //原始图像
bool is_showControlLines = true;

// 两个向量相加,p=p+q
 CvPoint3D32f pointAdd(CvPoint3D32f p, CvPoint3D32f q) 
{
    p.x += q.x; p.y += q.y; p.z += q.z;
    return p;
}

// 向量和标量相乘p=c*p
CvPoint3D32f pointTimes(float c, CvPoint3D32f p) 
{
    p.x *= c; p.y *= c; p.z *= c;
    return p;
}

// 计算贝塞尔方程的值
// 变量u的范围在0-1之间
//P1*t^3 + P2*3*t^2*(1-t) + P3*3*t*(1-t)^2 + P4*(1-t)^3 = Pnew 
CvPoint3D32f Bernstein(float u, CvPoint3D32f *p) 
{
    CvPoint3D32f a, b, c, d, r;

    a = pointTimes(pow(u,3), p[0]);
    b = pointTimes(3*pow(u,2)*(1-u), p[1]);
    c = pointTimes(3*u*pow((1-u),2), p[2]);
    d = pointTimes(pow((1-u),3), p[3]);

    r = pointAdd(pointAdd(a, b), pointAdd(c, d));

    return r;
}

//画控制线
void DrawControlLine(CvPoint3D32f *p) 
{
    CvPoint pc[4];
    for(int i=0;i<4;i++)
    {
        pc[i].x = (int)p[i].x;
        pc[i].y = (int)p[i].y;
    }

    cvLine(image,pc[0],pc[1],CV_RGB(0,0,255),1,CV_AA,0);
    cvLine(image,pc[2],pc[3],CV_RGB(0,0,255),1,CV_AA,0); 
}

//得到最近Control_pts的index
int getNearPointIndex(CvPoint mouse_pt)
{
    CvPoint pt;
    for(int i =0; i-1)
            conner_pt_index = -1;
        else
        {
            conner_pt_index = getNearPointIndex(pt); 
            //添加新的控制点
            if(conner_pt_index==-1)
            {
                if(mark_count<=(WW_MAX_MARK_COUNT-1))
                {
                    Control_pts[mark_count].x = (float)pt.x;
                    Control_pts[mark_count].y = (float)pt.y;
                    Control_pts[mark_count].z = 0;
                    mark_count++;
                }
            }
        }
    } 
    else  if ( event == CV_EVENT_MOUSEMOVE ) //修改控制点坐标
    {
        if(conner_pt_index >-1)
        {
            Control_pts[conner_pt_index].x = (float)x;
            Control_pts[conner_pt_index].y = (float)y;
        }
    }

};

int main(int argc, char* argv[])
{

    CvSize image_sz = cvSize( 1000,1000); 
    image = cvCreateImage(image_sz , 8, 3 );
    cvNamedWindow("Win",0);
    cvSetMouseCallback( "Win", on_mouse, 0 );
    cvResizeWindow("Win",500,500);

    cout<<"============== Bezier curve DEMO =============="<0) cvLine(image,pt_now,pt_pre,CV_RGB(230,255,0),2,CV_AA, 0 );
                pt_pre = pt_now;
            }

            //画控制线
            if(is_showControlLines)DrawControlLine(pControls);
            pControls+=3;
         }

    cvShowImage("Win",image);
    int keyCode = cvWaitKey(20);
    if (keyCode==27) break;
    if(keyCode=='w'||keyCode=='W') divs+=2; 
    if(keyCode=='s'||keyCode=='S') divs-=2; 
    if(keyCode=='z'||keyCode=='Z') is_showControlLines = is_showControlLines^1;

    //cout<<"precision : "<

你可能感兴趣的:(opencv)