绘制图形并填充

        =====文件名:DrawShape.h=====
#ifndef __DRAWINGS_H_INCLUDED__
#define __DRAWINGS_H_INCLUDED__

#include <wx/dc.h>
#include <wx/dcmemory.h>


//------------------------------------------------------------------------------

wxColour ChangeBrightness(const wxColour &ar_color, int percents)
{
    return wxColour(wxMin(255,int(ar_color.Red  ())*percents/100),
                    wxMin(255,int(ar_color.Green())*percents/100),
                    wxMin(255,int(ar_color.Blue ())*percents/100));
}

//------------------------------------------------------------------------------

void DrawGradientRect (wxDC& dc, wxRect rect, wxColour color_top, wxColour color_bottom, int a_transparency_percent=0)
{
    if (a_transparency_percent > 100) a_transparency_percent = 100;
    if (a_transparency_percent < 0) a_transparency_percent = 0;

    if (a_transparency_percent == 0)
    {
        dc.SetPen(*wxTRANSPARENT_PEN);
        int R0=color_top.Red(),
            G0=color_top.Green(),
            B0=color_top.Blue(),
            R1=color_bottom.Red(),
            G1=color_bottom.Green(),
            B1=color_bottom.Blue();
        int y;
        for (y=rect.GetTop(); y<=rect.GetBottom(); y++)
        {
            int R=R0+(R1-R0)*(y-rect.GetTop())/rect.GetHeight(),
                G=G0+(G1-G0)*(y-rect.GetTop())/rect.GetHeight(),
                B=B0+(B1-B0)*(y-rect.GetTop())/rect.GetHeight();
            dc.SetBrush(wxBrush(wxColour(R,G,B),wxSOLID));
            dc.DrawRectangle(rect.GetLeft(),y,rect.GetWidth(),1);
        }
    }
    else
    {
        wxBitmap bmp(rect.GetWidth(), rect.GetHeight());

        wxMemoryDC mem_dc;
        mem_dc.SelectObject(bmp);

        int R0=color_top.Red(),    G0=color_top.Green(), B0=color_top.Blue(),
            R1=color_bottom.Red(), G1=color_bottom.Green(), B1=color_bottom.Blue();
        for (int y=0; y<rect.GetHeight(); ++y)
        {
            int R=R0+((R1-R0)*y)/(rect.GetHeight() - 1),
                G=G0+((G1-G0)*y)/(rect.GetHeight() - 1),
                B=B0+((B1-B0)*y)/(rect.GetHeight() - 1);
            mem_dc.SetPen(wxPen(wxColour(R,G,B), 1, wxSOLID));
            mem_dc.DrawLine(0, y, rect.GetWidth()-1, y);
        }

        mem_dc.SelectObject(wxNullBitmap);

        wxImage img;
        img = bmp.ConvertToImage();
        img.InitAlpha();

        unsigned char *alpha_plane = img.GetAlpha();
        int alpha = (a_transparency_percent*255)/100;
        memset(alpha_plane, alpha, rect.GetWidth()*rect.GetHeight());

        wxBitmap final_bmp(img, 32);
        dc.DrawBitmap(final_bmp, rect.GetLeftTop(), true);
    }
}

//------------------------------------------------------------------------------

void DrawGradientCircle(wxDC& dc, wxPoint center, int radius, wxColour color_top, wxColour color_bottom)
{
    dc.SetPen(*wxTRANSPARENT_PEN);
    int R0=color_top.Red(),
        G0=color_top.Green(),
        B0=color_top.Blue(),
        R1=color_bottom.Red(),
        G1=color_bottom.Green(),
        B1=color_bottom.Blue();
    int y;
    for (y=-radius; y<=radius; y++)
    {
        int R=R0+(R1-R0)*(y+radius)/(2*radius),
            G=G0+(G1-G0)*(y+radius)/(2*radius),
            B=B0+(B1-B0)*(y+radius)/(2*radius);
        dc.SetBrush(wxBrush(wxColour(R,G,B),wxSOLID));
        double r=y;
        if (r<0)
            r=-r;
        r=wxMax(0.0,r-0.5);
        int x=int(sqrt(double(radius*radius-r*r))+0.5);
        dc.DrawRectangle(center.x-x,center.y+y,x*2+1,1);
    }
}

//------------------------------------------------------------------------------

void DrawGradientSphere(wxDC& dc, wxPoint center, int radius, wxColour color)
{
    dc.SetPen(*wxTRANSPARENT_PEN);
    int R0=color.Red(),
        G0=color.Green(),
        B0=color.Blue();
    int dcol=wxMin(255-R0,wxMin(255-G0,255-B0));
    int R1=R0+dcol,
        G1=G0+dcol,
        B1=B0+dcol;
    wxColour dark=ChangeBrightness(color,50);
    int R2=dark.Red(),
        G2=dark.Green(),
        B2=dark.Blue();
    int R,G,B;
    for (int y=radius*2; y>0; y--)
    {
        if (y>radius)
        {
            R=R0+(R2-R0)*(y-radius)/radius;
            G=G0+(G2-G0)*(y-radius)/radius;
            B=B0+(B2-B0)*(y-radius)/radius;
        }
        else
        {
            R=R1+(R0-R1)*y/radius;
            G=G1+(G0-G1)*y/radius;
            B=B1+(B0-B1)*y/radius;
        }
        dc.SetBrush(wxColour(R,G,B));
        dc.DrawEllipse(center.x-(radius*2-y)/6-(y+1)/2,
                       center.y-(radius*2-y)/6-(y+1)/2,
                       y+1,
                       y+1);
    }
/*    int y;
    int h=radius*2/3;
    for (y=-radius; y<=radius; y++)
    {
        if (y+radius<h)
        {
            R=R0+(R1-R0)*(y+radius)/h;
            G=G0+(G1-G0)*(y+radius)/h;
            B=B0+(B1-B0)*(y+radius)/h;
        }
        else if (y+radius<2*h)
        {
            R=R1+(R0-R1)*(y+radius-h)/h;
            G=G1+(G0-G1)*(y+radius-h)/h;
            B=B1+(B0-B1)*(y+radius-h)/h;
        }
        else
        {
            R=R0+(R2-R0)*(y+radius-2*h)/h;
            G=G0+(G2-G0)*(y+radius-2*h)/h;
            B=B0+(B2-B0)*(y+radius-2*h)/h;
        }
        dc.SetBrush(wxBrush(wxColour(R,G,B),wxSOLID));
        double r=y;
        if (r<0)
            r=-r;
        r=wxMax(0.0,r-0.5);
        int x=int(sqrt(double(radius*radius-r*r))+0.5);
        dc.DrawRectangle(center.x-x,center.y+y,x*2+1,1);
    }
*/
}

//------------------------------------------------------------------------------

void DrawCylinderHor(wxDC& dc, wxRect rect, wxColour color)
{
    dc.SetPen(*wxTRANSPARENT_PEN);
    int R=color.Red(),
        G=color.Green(),
        B=color.Blue();
    int dcol=wxMin(255-R,wxMin(255-G,255-B));
    R+=dcol;
    G+=dcol;
    B+=dcol;
    wxColour dark=ChangeBrightness(color,50);
    int h=rect.height/3;
    DrawGradientRect(dc,wxRect(rect.x,rect.y    ,rect.width,h),color,wxColour(R,G,B));
    DrawGradientRect(dc,wxRect(rect.x,rect.y+h  ,rect.width,h),wxColour(R,G,B),color);
    DrawGradientRect(dc,wxRect(rect.x,rect.y+h*2,rect.width,rect.height-h*2),color,dark);
}

//------------------------------------------------------------------------------

void CalcEllipsePoint (wxRect rect, wxPoint *pts)
{
    double a=rect.width;
    double b=rect.height;
    a/=2;
    b/=2;
    pts[0]=wxPoint(rect.x,rect.y+rect.height/2);
    pts[rect.width]=wxPoint(rect.x+rect.width,rect.y+rect.height/2);
    for (int x=1; x<rect.width; x++)
    {
        double x1=double(rect.width)/2-x;
        double y=b/a*sqrt(wxMax(0,a*a-x1*x1));
        pts[x              ].x=
        pts[rect.width*2-x].x=rect.x+x;
        pts[x              ].y=int(rect.y+double(rect.height)/2+y);
        pts[rect.width*2-x].y=int(rect.y+double(rect.height)/2-y);
    }
}

void DrawCylinderVer(wxDC& dc, wxRect rect, wxColour color)
{
    wxPoint *pts=new wxPoint[rect.width*2];
    wxRect el_rect=rect;
    el_rect.y-=rect.width/4;
    el_rect.height=rect.width/2;
    CalcEllipsePoint(el_rect,pts);
    dc.SetBrush(color);
    dc.SetPen(color);
    dc.DrawPolygon(rect.width*2,pts);

    int R1=color.Red(),
        G1=color.Green(),
        B1=color.Blue();
    int dcol=wxMin(255-R1,wxMin(255-G1,255-B1));
    int R2=R1+dcol,
        G2=G1+dcol,
        B2=B1+dcol;
    wxColour dark=ChangeBrightness(color,50);
    int R3=color.Red(),
        G3=color.Green(),
        B3=color.Blue();
    int w_3=rect.width/3;
    for (int i=0; i<=rect.width; i++)
    {
        wxColour col;
        if (i<w_3)
            col=wxColour(R1+i*(R2-R1)/w_3,
                         G1+i*(G2-G1)/w_3,
                         B1+i*(B2-B1)/w_3);
        else if (i<w_3*2)
            col=wxColour(R2+(i-w_3)*(R1-R2)/w_3,
                         G2+(i-w_3)*(G1-G2)/w_3,
                         B2+(i-w_3)*(B1-B2)/w_3);
        else
            col=wxColour(R1+(i-w_3*2)*(R3-R1)/w_3,
                         G1+(i-w_3*2)*(G3-G1)/w_3,
                         B1+(i-w_3*2)*(B3-B1)/w_3);
        dc.SetPen(col);
        dc.DrawLine(rect.x+i,pts[i].y,rect.x+i,pts[i].y+rect.height);
    }
    delete[] pts;
}

//------------------------------------------------------------------------------

void DrawCylinderVerHatch(wxDC& dc, wxRect rect, wxColour color)
{
    wxPoint *pts=new wxPoint[rect.width*2+2];
    wxRect el_rect=rect;
    el_rect.y-=rect.width/4;
    el_rect.height=rect.width/2;
    CalcEllipsePoint(el_rect,pts);
    for (int i=rect.width*2+1; i>=0; i--)
    {
        if (i==rect.width*2+1)
            pts[i]=pts[0];
        else if (i>rect.width)
        {
            pts[i].x=pts[i-1].x;
            pts[i].y=pts[i-1].y;
        }
        else if (i<=rect.width)
            pts[i].y+=rect.height;
    }
    dc.SetBrush(wxBrush(color, wxBDIAGONAL_HATCH));
    dc.SetPen(color);
    dc.DrawPolygon(rect.width*2+2,pts);
    CalcEllipsePoint(el_rect,pts);
    dc.SetBrush(*wxWHITE);
    dc.DrawPolygon(rect.width*2,pts);
}

//------------------------------------------------------------------------------

void DrawCylinderVerContour(wxDC& dc, wxRect rect, wxColour color)
{
    wxPoint *pts=new wxPoint[rect.width*2+2];
    wxRect el_rect=rect;
    el_rect.y-=rect.width/3;
    el_rect.height=rect.width*2/3;
    CalcEllipsePoint(el_rect,pts);
    for (int i=rect.width*2+1; i>=0; i--)
    {
        if (i==rect.width*2+1)
            pts[i]=pts[0];
        else if (i>rect.width)
        {
            pts[i].x=pts[i-1].x;
            pts[i].y=pts[i-1].y;
        }
        else if (i<=rect.width)
            pts[i].y+=rect.height;
    }
    dc.SetBrush(*wxTRANSPARENT_BRUSH);
    dc.SetPen(color);
    dc.DrawPolygon(rect.width*2+2,pts);
}


#endif // __DRAWINGS_H_INCLUDED__
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值