1)画的时候是逆时针画,因为圆的正角是逆时针的.
(2)Pie的nLeftRect nTopRect nRightRect nBottomRect 参数确定这个饼(一个椭圆,而不是圆)所在的矩形局域,实际上就是确定了原点
(3)Pie的nXRadial1 nYRadial1 nXRadial2 nYRadial2 确定一个扇形的两个夹角的位置
(4)在数学上,对扇形的计算用弧度,而不是度.弧度是这样规定的2π*弧度=360°,也就是说1°=π/180弧度.通过数学理论知道,扇形的某个点要通过sin,cos函数与扇形半径的乘积来获取.
(5)在数学上,sin,cos的参数是度(°),而在c++函数中,他们的参数不是度,而是弧度.
(6)Pie函数的缺陷:当扇形的两个夹角(的坐标)完全相同时,也就是x1=x2,y1=y2时,它会填满整个饼,也就是一个360的扇形,所以当两个点近似时,由于计算的精确度,这两个点的坐标值可能完全相同,此时便不正常的画360扇形了,目前采取的方法是,如果两个点相同,则画图循环跳出,反正剩下的那点肉眼看不出来.
(7)Pie的参数都是int类型,所以使用double以求更高的精确度没有意义
void C3DPie::DrawPie(HWND &hwnd)
{
ReformatPieArray();
OnCreate(hwnd);
//*********************************
HDC hdc=GetDC(hwnd);
CDC* pDC=CDC::FromHandle(hdc);
CBitmap* pOldBitmap=pMemDC->SelectObject(pBitmap);
CBrush myBrush(RGB(255,255,255));
pMemDC->FillRect(CRect(-1,-1,m_nMaxX,m_nMaxY),&myBrush);
double pi =3.141592; //
int zdX=m_x+m_w/2;
int zdY=m_y+m_h/2;
int x1=m_x+m_w;
int y1=m_y+m_h/2;
int jd=0;//
CPen * poldpen;
int num=m_piearray.GetSize();
///
int oldx = 0,oldy = 0;
for(int m=0;m<num;m++)
{
jd+=m_piearray[m];
int p=m;
CBrush brush(dwoncolor[p]);
pMemDC->SelectObject(&brush);
int x=m_w/2*cos(jd*pi/180);
int y=m_h/2*sin(jd*pi/180);
if (x == oldx && y == oldy)//扇形的两个角坐标完全相同时,会填满整个饼
{
break;
}
CPen pen;
pen.CreatePen(PS_SOLID,0,dwoncolor[p]);
poldpen=pMemDC->SelectObject(&pen);
Pie( pMemDC->m_hDC,
m_x,
m_y,
m_x+m_w,
m_y+m_h,
x1,
y1,
zdX+x,
zdY-y
);
x1=zdX+x;
y1=zdY-y;
oldx = x;
oldy = y;
}
/
jd=0;
for(int i=0;i<num;i++)
{
jd+=m_piearray[i];
// int p=num-1-i;
int p=i;
CBrush brush(upcolor[p]);
pMemDC->SelectObject(&brush);
int x=m_w/2*cos(jd*pi/180);
int y=m_h/2*sin(jd*pi/180);
CPen pen;
pen.CreatePen(PS_SOLID,0,upcolor[p]);
poldpen=pMemDC->SelectObject(&pen);
// Pie( pMemDC->m_hDC,m_x,m_y,m_x+m_w,m_y+m_h,x1,y1,zdX+x,zdY-y);//使用上面的画图函数
int half=m_piearray[i]/3;
int sx=zdX+m_w/1.3*cos((jd-half)*pi/180);
int sy=zdY-m_h/1.3*sin((jd-half)*pi/180);
int ox=zdX+m_w/4*cos((jd-half)*pi/180);
int oy=zdY-m_h/4*sin((jd-half)*pi/180);
CPen spen;
spen.CreatePen(PS_SOLID,1,RGB(0,0,0));
CPen* plp=pMemDC->SelectObject(&spen);
pMemDC->MoveTo(sx,sy);
pMemDC->LineTo(ox,oy);
pMemDC->SelectObject(plp);
CString text;
text.Format("%.2f",((float)m_piearray[i]/360.0)*100);
pMemDC->TextOut(sx,sy,text+"%");
x1=zdX+x;
y1=zdY-y;
}
CRect m_rect;
GetWindowRect(hwnd, m_rect);
int size=m_item.GetSize();
for(i=0;i<size;i++)
{
pMemDC->TextOut(m_x+440,(m_rect.bottom * 0.45)-20*i,m_item[i]);
CRect rect(m_x+400,m_rect.bottom * 0.45-20*i,m_x+430,m_rect.bottom * 0.45+18-20*i);
pMemDC->Rectangle(&rect);
CRect frect(m_x+401,m_rect.bottom * 0.45+1-20*i,m_x+429,m_rect.bottom * 0.45+17-20*i);
CBrush bqbrush(upcolor[i]);
pMemDC->FillRect(&frect,&bqbrush);
}
pMemDC->SelectObject(poldpen);
pDC->BitBlt(-1,-1,m_nMaxX,m_nMaxY,pMemDC,0,0,SRCCOPY);
pMemDC->SelectObject(pOldBitmap);
::ReleaseDC(NULL,(HDC)pMemDC);
ReleaseDC(hwnd,hdc);
}