Pie画饼图

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值