在我的工程里都严格验证可行的, 把关键性的算法抠出来就行.
1: 利用三角形内部一点到三角形三个顶点的连线组成的三个小三角形面积总和等于此三角形的面积。
static float get_area(POINT t0,POINT t1,POINT t2)
{
float area = 0.0;
area =(float)((t0.x * t1.y + t1.x * t2.y + t2.x * t0.y - t1.x * t0.y - t2.x * t1.y - t0.x * t2.y)*0.5);
area = area > 0 ? area : -area;
return area;
}
BOOL GUIAPI
Polygon_ex_2(
HDC hDC,
POINT *lpPoints,
int nCount
)
{
POINT tmpPoint;
POINT point;
int i;
int x3, y3, state;
POINT point0,point1,point2;
int iMinx,iMiny,iMaxx,iMaxy;
int xx,yy;
float s0,s1,s2,s;
float d;
COLORREF crColor;
if(!hDC)
return false;
if(nCount<3)
return false;
crColor=((PEN*)(hDC->hPen))->crPenColor;
//backup current point
point.x = hDC->point.x;
point.y = hDC->point.y;
point0 = lpPoints[0];
point1 = lpPoints[1];
point2 = lpPoints[2];
iMinx = min(point0.x, point1.x);
iMinx = min(iMinx, point2.x);
iMiny = min(point0.y, point1.y);
iMiny = min(iMiny, point2.y);
iMaxx = max(point0.x, point1.x);
iMaxx = max(iMaxx, point2.x);
iMaxy = max(point0.y, point1.y);
iMaxy = max(iMaxy, point2.y);
for(yy = iMiny; yy <= iMaxy ;yy++)
{
for(xx = iMinx; xx <= iMaxx ;xx++)
{
tmpPoint.x = xx;
tmpPoint.y = yy;
s = get_area(point0,point1,point2);
s0 = get_area(tmpPoint,point1,point2);
s1 = get_area(tmpPoint,point0,point2);
s2 = get_area(tmpPoint,point0,point1);
d = s - s0 -s1 -s2;
d = d > 0 ? d : -d;
if(d < 0.0001)
{
MoveToEx(hDC,xx,yy,&tmpPoint);
cliSetPixel(hDC,xx,yy,crColor);
}
}
}
//restore current point
hDC->point.x = point.x;
hDC->point.y = point.y;
return true;
}
2:利用向量原理:
沿 △ABC 各有向边按一定方向走(顺时针或逆时针),判断点 P 是否在该边的某侧(右侧或左侧),若点 P 在三条边的同侧,则点 P 在 △ABC 内
static BOOL isOnSameSide(POINT t0,POINT t1,POINT t2,POINT t3)
{
int a,b,c;
int x0,x1,x2,x3,y0,y1,y2,y3;
x0 = t0.x;
y0 = t0.y;
x1 = t1.x;
y1 = t1.y;
x2 = t2.x;
y2 = t2.y;
x3 = t3.x;
y3 = t3.y;
a = y0 - y1;
b = x1 - x0;
c = x0 * y1 - x1 * y0;
if( (a * x2 + b * y2 + c) * (a * x3 + b * y3 + c) > 0)
{
return true;
}
return false;
}
BOOL GUIAPI
FillTriangle(
HDC hDC,
POINT *lpPoints,
int nCount
)
{
POINT tmpPoint;
POINT point;
int i;
int x3, y3, state;
POINT point0,point1,point2;
int iMinx,iMiny,iMaxx,iMaxy;
int xx,yy;
float s0,s1,s2,s;
float d;
COLORREF crColor;
if(!hDC)
return false;
if(nCount<3)
return false;
crColor=((PEN*)(hDC->hPen))->crPenColor;
//backup current point
point.x = hDC->point.x;
point.y = hDC->point.y;
point0 = lpPoints[0];
point1 = lpPoints[1];
point2 = lpPoints[2];
iMinx = min(point0.x, point1.x);
iMinx = min(iMinx, point2.x);
iMiny = min(point0.y, point1.y);
iMiny = min(iMiny, point2.y);
iMaxx = max(point0.x, point1.x);
iMaxx = max(iMaxx, point2.x);
iMaxy = max(point0.y, point1.y);
iMaxy = max(iMaxy, point2.y);
for(yy = iMiny; yy <= iMaxy ;yy++)
{
for(xx = iMinx; xx <= iMaxx ;xx++)
{
tmpPoint.x = xx;
tmpPoint.y = yy;
if(isOnSameSide(tmpPoint,point0,point1,point2) ||
isOnSameSide(tmpPoint,point1,point2,point0) ||
isOnSameSide(tmpPoint,point2,point0,point1))
{
}
else
{
MoveToEx(hDC,xx,yy,&tmpPoint);
cliSetPixel(hDC,xx,yy,crColor);
}
}
}
//restore current point
hDC->point.x = point.x;
hDC->point.y = point.y;
return true;
}