三角形的两种画法

在我的工程里都严格验证可行的, 把关键性的算法抠出来就行.

 

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值