program using VC
user can click and move the 4 control points, the curve will update when the point is moving..
CPoint points[4];
int ptSize = 10;
int nCaptured = -1;
CTestBezierView::CTestBezierView()
{
// TODO: add construction code here
points[0] = CPoint(5,10);
points[1] = CPoint(100,100);
points[2] = CPoint(200,100);
points[3] = CPoint(400,300);
}
void CTestBezierView::OnDraw(CDC* pDC)
{
CTestBezierDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
for(int i=0; i<4; i++)
{
CRect rect (points[i].x - ptSize,
points[i].y - ptSize,
points[i].x + ptSize,
points[i].y + ptSize);
pDC->Rectangle(rect);
}
//draw Bezier curve
#define NumPts 100
for(i=0; i<NumPts; i++)
{
double u = i*1.0/NumPts;
double B0 = (1.0-u)*(1.0-u)*(1.0-u);
double B1 = 3 * u * (1-u) * (1-u);
double B2 = 3 * u * u * (1-u);
double B3 = u * u * u;
int x = points[0].x * B0 + points[1].x * B1
+ points[2].x * B2 + points[3].x * B3;
int y = points[0].y * B0 + points[1].y * B1
+ points[2].y * B2 + points[3].y * B3;
if(i==0)
pDC->MoveTo(x,y);
else
pDC->LineTo(x,y);
}
}
void CTestBezierView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
for(int i=0; i<4; i++)
{
CRect rect (points[i].x - ptSize,
points[i].y - ptSize,
points[i].x + ptSize,
points[i].y + ptSize);
if(PtInRect(rect, point))
{
nCaptured = i;
SetCapture(); //can get mouse event even mouse even out of region
break;
}
}
CView::OnLButtonDown(nFlags, point);
}
void CTestBezierView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(nCaptured>=0)
{
nCaptured = -1;
ReleaseCapture();
Invalidate();
}
CView::OnLButtonUp(nFlags, point);
}
void CTestBezierView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(nCaptured>=0 )
{
CRect rect;
GetClientRect(rect);
if(PtInRect(rect, point))
{
points[nCaptured] = point;
Invalidate();
}
}
CView::OnMouseMove(nFlags, point);
}