From ca74184d390f50dba5a24c6c016930f0b28f76ae Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 18:16:23 +0800 Subject: [PATCH] added DrawGeometry.h --- inc/hgl/2d/DrawGeometry.h | 409 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 inc/hgl/2d/DrawGeometry.h diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h new file mode 100644 index 0000000..17b33e3 --- /dev/null +++ b/inc/hgl/2d/DrawGeometry.h @@ -0,0 +1,409 @@ +#pragma once + +#include +#include + +namespace hgl +{ + template class DrawGeometry + { + public: + + using FormatBitmap=Bitmap; + + protected: + + FormatBitmap *bitmap; + + T draw_color; + + public: + + DrawGeometry(FormatBitmap *fb) + { + bitmap=fb; + } + + virtual ~DrawGeometry()=default; + + virtual void SetDrawColor(const T &color) + { + draw_color=color; + } + + bool GetPixel(int x,int y,T &color) + { + if(!data)return(false); + + T *p=GetData(x,y); + + if(!p)return(false); + + color=*p; + + return(true); + } + + bool PutPixel(int x,int y) + { + if(!bitmap)return(false); + + T *p=bitmap->GetData(x,y); + + if(!p)return(false); + + *p=draw_color; + + return(true); + } + + bool DrawHLine(int x,int y,int length) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(y<0||y>=height)return(false); + if(x>=width)return(false); + if(x<0){length+=x;x=0;} + if(x+length>width)length=width-x; + + if(length<=0)return(false); + + FillPixels(bitmap->GetData(x,y),draw_color,length); + + return(true); + } + + bool DrawBar(int l,int t,int w,int h) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(l>=width||t>=height)return(false); + + if(l<0){w+=l;l=0;} + if(t<0){h+=t;t=0;} + + if(l+w>width)w=width-l; + if(t+h>height)h=height-t; + + if(w<=0||h<=0)return(false); + + for(int y=t;y(bitmap->GetData(l,y),draw_color,w); + + return(true); + } + + bool DrawVLine(int x,int y,int length) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(x<0||x>=width)return(false); + if(y>=height)return(false); + if(y<0){length+=y;y=0;} + if(y+length>height)length=height-y; + + if(length<=0)return(false); + + const uint line_bytes=bitmap->GetLineBytes(); + T *p=bitmap->GetData(x,y); + + for(int i=0;i=0) + { + tn+=(6+((x-y)<<2)); + y--; + } + else + tn+=((x<<2)+2); + + PutPixel(x0+y,y0+x); + PutPixel(x0+x,y0+y); + PutPixel(x0-x,y0+y); + PutPixel(x0-y,y0+x); + PutPixel(x0-y,y0-x); + PutPixel(x0-x,y0-y); + PutPixel(x0+x,y0-y); + PutPixel(x0+y,y0-x); + + x++; + } + + PutPixel(x0+y,y0+x); + PutPixel(x0+x,y0+y); + PutPixel(x0-x,y0+y); + PutPixel(x0-y,y0+x); + PutPixel(x0-y,y0-x); + PutPixel(x0-x,y0-y); + PutPixel(x0+x,y0-y); + PutPixel(x0+y,y0-x); + + return(true); + } + + bool DrawSolidCircle(int x,int y,int radius) + { + if(!bitmap)return(false); + + if(radius<=0)return(false); + + int x0=x-radius; + int y0=y-radius; + int x1=x+radius; + int y1=y+radius; + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(x0<0)x0=0; + if(y0<0)y0=0; + if(x1>=width)x1=width-1; + if(y1>=height)y1=height-1; + + if(x0>x1||y0>y1)return(false); + + int r2=radius*radius; + + for(int cy=y0;cy<=y1;cy++) + { + int dy=cy-y; + int dy2=dy*dy; + + for(int cx=x0;cx<=x1;cx++) + { + int dx=cx-x; + int dx2=dx*dx; + + if(dx2+dy2<=r2) + PutPixel(cx,cy); + } + } + + return(true); + } + + void DrawLine(int x1, int y1, int x2, int y2) + { + int p, n, x, y, tn; + + if(y1==y2) + { + if(x1>x2) + { + x=x2;x2=x1;x1=x; + } + + DrawHLine(x1, y1, x2-x1+1); + return; + } + + if(x1==x2) + { + if(y1>y2) + { + y=y2;y2=y1;y1=y; + } + + DrawVLine(x1, y1, y2-y1+1); + return; + } + + if(abs(y2-y1)<=abs(x2-x1)) + { + if((y2x2)) + { + x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; + } + + if(y2>=y1&&x2>=x1) + { + x=x2-x1;y=y2-y1; + p=2*y;n=2*x-2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1++; } + + PutPixel(x1++, y1); + } + } + else + { + x=x2-x1;y=y2-y1; + p=-2*y;n=2*x+2*y;tn=x; + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1--; } + + PutPixel(x1++, y1); + } + } + } + else + { + x=x1;x1=y2;y2=x;y=y1;y1=x2;x2=y; + + if((y2x2)) + { + x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; + } + + if(y2>=y1&&x2>=x1) + { + x=x2-x1;y=y2-y1;p=2*y;n=2*x-2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1++; } + + PutPixel(y1, x1++); + } + } + else + { + x=x2-x1;y=y2-y1;p=-2*y;n=2*x+2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1--; } + + PutPixel(y1, x1++); + } + } + } + } + + void DrawSector(int x0, int y0, uint r, uint stangle, uint endangle) + { + int i, j; + int *xy; + int bx, ex, bxd, exd, bxf, exf, ben; + int tn, x, y; + int xmax; + + y=r; x=0; + xmax=(int)(r*HGL_SIN_45); + tn=(1-r*2); + + xy=(int *)calloc(20, sizeof(int)); + xy[0]=x0+r;xy[1]=y0; + xy[2]=x0; xy[3]=y0-r; + xy[4]=x0; xy[5]=y0-r; + xy[6]=x0-r;xy[7]=y0; + xy[8]=x0-r;xy[9]=y0; + xy[10]=x0; xy[11]=y0+r; + xy[12]=x0; xy[13]=y0+r; + xy[14]=x0+r;xy[15]=y0; + + bx=stangle/45; + ex=endangle/45; + ben=ex-bx-1; + + xy[16]=(int)(r*Lcos(stangle)); + xy[17]=(int)(r*Lsin(stangle)); + xy[18]=(int)(r*Lcos(endangle)); + xy[19]=(int)(r*Lsin(endangle)); + + DrawLine(x0+xy[16], y0-xy[17], x0, y0); + DrawLine(x0+xy[18], y0-xy[19], x0, y0); + + if(bx==1||bx==2||bx==5||bx==6)bxd=abs(xy[16]);else bxd=abs(xy[17]); + if(ex==1||ex==2||ex==5||ex==6)exd=abs(xy[18]);else exd=abs(xy[19]); + if(bx==0||bx==2||bx==4||bx==6)bxf=0; else bxf=1; + if(ex==0||ex==2||ex==4||ex==6)exf=1; else exf=0; + + while(x<=xmax) + { + if(tn>=0) + { + tn+=(6+((x-y)*4)); + y--; + xy[0]--; + xy[3]++; + xy[5]++; + xy[6]++; + xy[8]++; + xy[11]--; + xy[13]--; + xy[14]--; + } + else tn+=((x*4)+2); + + if(stangleendangle) + { + j=(bx+1)*2; + for(i=bx+1;i<8;i++) + { + PutPixel(xy[j], xy[j+1]); + j+=2; + } + j=0; + for(i=0;ibxd)^bxf)PutPixel(xy[i], xy[i+1]);i=ex*2; + if((x>exd)^exf)PutPixel(xy[i], xy[i+1]);x++; + xy[1]--; + xy[2]++; + xy[4]--; + xy[7]--; + xy[9]++; + xy[10]--; + xy[12]++; + xy[15]++; + } + free(xy); + } + };//template class DrawGeometry +}//namespace hgl