绘制图形并填充
程序员文章站
2022-03-28 15:01:44
...
=====文件名: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__