关于Bezier曲线的拾取?
这是我写的3次Bezier曲线的拾取,但是有盲点。有时候明明鼠标在线上,但是就是判断不到,郁闷呀。希望有人能提出更好的算法。。
BOOL CBaseBezier3::HitTest(CPoint ptHit)
{
CRgn rgHit;
rgHit.CreatePolygonRgn(m_ptCtrl,4,WINDING);
if(!rgHit.PtInRegion(ptHit))
return FALSE;
//控制点。
CPoint p0,p1,p2,p3;
p0 = m_ptCtrl[0];
p1 = m_ptCtrl[1];
p2 = m_ptCtrl[2];
p3 = m_ptCtrl[3];
int i = 0;
UINT dx = abs(p0.x - p3.x); // x 变化量
UINT dy = abs(p0.y - p3.y); // y 变化量
dy = dx > dy ? dx : dy;
double step = 1.0 / dy; // 步长
long x, y;
double t3, t2, t11, t12, t13;
// x = (1-t)^3 *x0 + 3*t*(1-t)^2 *x1 + 3*t^2*(1-t) *x2 + t^3 *x3
// y = (1-t)^3 *y0 + 3*t*(1-t)^2 *y1 + 3*t^2*(1-t) *y2 + t^3 *y3
// 0 <= t <= 1
CPoint ptPre,ptCur;
double t = 0.0;
ptPre = p0;
for( t = step; t < 1.0; t += step ) {
t11 = 1-t;
t12 = t11 * t11;
t13 = t12 * t11;
t2 = t * t;
t3 = t2 * t;
double t_t12_3 = 3 * t * t12 ;
double t2_t11_3 = 3 * t2 * t11;
x = static_cast<long>( t13 * p0.x + t_t12_3 * p1.x + t2_t11_3 * p2.x + t3 * p3.x);
y = static_cast<long>( t13 * p0.y + t_t12_3 * p1.y + t2_t11_3 * p2.y + t3 * p3.y);
CPoint ptTemp(x,y);
CRect rcTemp(ptPre,ptTemp);
rcTemp.NormalizeRect();
int iInflate = MIN_DISTANCE;//MIN_DISTANCE=5
if(rcTemp.Height() < MIN_DISTANCE)
rcTemp.InflateRect(0,iInflate);
if(rcTemp.Width() < MIN_DISTANCE)
rcTemp.InflateRect(iInflate,0);
rcTemp.InflateRect(1,1);
if(rcTemp.PtInRect(ptHit))
return TRUE;
ptPre = ptTemp;
}
return FALSE;
}