drawmethod.cpp
资源名称:eDraw2 [点击查看]
上传用户:fjzzwyy
上传日期:2007-01-14
资源大小:244k
文件大小:14k
源码类别:
绘图程序
开发平台:
Visual C++
- #include "stdafx.h"
- #include "DrawMethod.h"
- CDC * MyDC;
- COLORREF Mycol;
- int round(float ff)
- {
- int k;
- if((ff-(int)ff)>0.5) k=(int)ff+1;
- else k=(int)ff;
- return k;
- }
- int sign(int num)
- {
- if (num==0) return 0;
- return num>0?1:-1;
- }
- int getmax(int point[],int n)
- {
- int max=point[0];
- for(int i=1;i<=n-1;i++)
- {
- if(max<point[i]) max=point[i];
- }
- return max;
- }
- //取顶点坐标的最小值
- int getmin(int point[],int n)
- {
- int min=point[0];
- for(int j=1;j<=n-1;j++)
- {
- if(min>point[j]) min=point[j];
- }
- return min;
- }
- void DrawMyLine(CDC* pDC,CPoint A,CPoint B,COLORREF Color)
- {
- int dx,dy;
- int px,py;
- int cx=0,cy=0;
- dx=abs(A.x-B.x)+1;
- dy=abs(A.y-B.y)+1;
- pDC->SetPixelV(A,Color);
- pDC->SetPixelV(B,Color);
- px=A.x;py=A.y;
- int count=dx+dy-3;
- if (A.x<B.x){
- if (A.y<B.y) {
- cx+=dy;cy+=dx;
- for (int i=0;i<count;i++){
- if (cx<cy) {px+=1;cx+=dy;} else {py+=1;cy+=dx;}
- pDC->SetPixelV(px,py,Color);
- }
- }else{
- cx+=dy;cy+=dx;
- for (int i=0;i<count;i++){
- if (cx<cy) {px+=1;cx+=dy;} else {py-=1;cy+=dx;}
- pDC->SetPixelV(px,py,Color);
- }
- }
- }else{
- if (A.y<B.y) {
- cx+=dy;cy+=dx;
- for (int i=0;i<count;i++){
- if (cx<cy) {px-=1;cx+=dy;} else {py+=1;cy+=dx;}
- pDC->SetPixelV(px,py,Color);
- }
- }else{
- cx+=dy;cy+=dx;
- for (int i=0;i<count;i++){
- if (cx<cy) {px-=1;cx+=dy;} else {py-=1;cy+=dx;}
- pDC->SetPixelV(px,py,Color);
- }
- }
- }
- }
- bool DrawLine_BPB(CDC * pDC,int x1,int y1,int x2,int y2,COLORREF Color)
- {
- if((x1==x2)&&(y1==y2)) {
- pDC->SetPixelV(x1,y1,Color);
- return true;
- }
- ///////直线竖直/////////////////
- if(x1== x2){
- int maxy=y1>y2?y1:y2;
- int miny=y1<y2?y1:y2;
- for(int i=miny; i<=maxy;i++)
- pDC->SetPixelV(x1,i,Color);
- return true;
- }
- ///////直线水平////////////////
- if(y1==y2){
- int maxx=x1>x2?x1:x2;
- int minx=x1<x2?x1:x2;
- for(int i=minx; i<=maxx;i++)
- pDC->SetPixelV(i,y1,Color);
- return true;
- }
- int x,y;
- int dx,dy,c,f;
- dx=abs(x2-x1);
- dy=abs(y1-y2);
- ///////c为计步长///////////////////
- if(dx>=dy) c=dx;else c=dy;
- x=x1;y=y1;f=0;
- while(c>=0)
- {
- pDC->SetPixelV(x,y,Color);
- if(f>=0){
- if(x2>x1) x++;else x--;
- f-=dy;
- if(dx>dy) c--;
- }
- else{
- if(y2<y1) y--;else y++;
- f+=dx;
- if(dx<=dy) c--;
- }
- }
- pDC->SetPixelV(x,y,Color);
- return true;
- }
- void DrawLine_DDA(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
- {
- float ddx,ddy,x,y;
- int dx,dy,i,j;
- int b=1,c=0,d=1;
- float a=1.0;
- float n=1.0;
- dx=xb-xa;dy=yb-ya;
- if(dx<0) b=-1; //b判定x的走向
- if(dy<0) d=-1; //d判定y的走向
- dx=abs(dx);dy=abs(dy);
- if(dx>dy) c=dx;else c=dy;
- ddx=(float)dx/c;ddy=(float)dy/c;
- x=(float)xa;y=(float)ya;
- while(c>=0){
- i=round(x);j=round(y);
- pDC->SetPixelV(i,j,Color);
- x=x+b*ddx;y=y+d*ddy;c--;
- }
- }
- void DrawLine_Thick(CDC* pDC,int xa,int ya,int xb,int yb,int width,COLORREF Color)
- {
- int q,i,x,y,k,dx,dy,s1,s2,temp,interchange,e;
- q=width/2;
- x=xa;y=ya;
- dx=abs(xb-xa);
- dy=abs(yb-ya);
- s1=sign(xb-xa);
- s2=sign(yb-ya);
- if ((s1==0)&&(s2==0)) return;
- if (dy>dx) {
- temp=dx;
- dx=dy;
- dy=temp;
- interchange=1;
- }else {
- interchange=0;
- }
- e=2*dy-dx;
- for (i=0;i<=dx;i++){
- if (interchange)
- for (k=-q;k<=q;k++)
- pDC->SetPixelV(x+k,y,Color);
- else
- for (k=-q;k<=q;k++)
- pDC->SetPixelV(x,y+k,Color);
- while (e>=0){
- if (interchange==1) x+=s1;else y+=s2;
- e-=dx+dx;
- }
- if (interchange==1) y+=s2; else x+=s1;
- e+=2*dy;
- }
- }
- void DrawLine_BresenHam(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
- {
- int i,x,y,dx,dy,s1,s2,temp,interchange,e;
- x=xa;y=ya;
- dx=abs(xb-xa);
- dy=abs(yb-ya);
- s1=sign(xb-xa);
- s2=sign(yb-ya);
- if ((s1==0)&&(s2==0)) return;
- if (dy>dx) {
- temp=dx;
- dx=dy;
- dy=temp;
- interchange=1;
- }else {
- interchange=0;
- }
- e=2*dy-dx;
- for (i=0;i<=dx;i++){
- pDC->SetPixelV(x,y,Color);
- while (e>=0){
- if (interchange==1) x+=s1;else y+=s2;
- e-=dx+dx;
- }
- if (interchange==1) y+=s2; else x+=s1;
- e+=2*dy;
- }
- }
- void DrawLine_BresenHam_Broken(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
- {
- int i,x,y,dx,dy,s1,s2,temp,interchange,e,count,draw;
- x=xa;y=ya;count=0;draw=1;
- dx=abs(xb-xa);
- dy=abs(yb-ya);
- s1=sign(xb-xa);
- s2=sign(yb-ya);
- if ((s1==0)&&(s2==0)) return;
- if (dy>dx) {
- temp=dx;
- dx=dy;
- dy=temp;
- interchange=1;
- }else {
- interchange=0;
- }
- e=2*dy-dx;
- for (i=0;i<=dx;i++){
- count++;
- if (draw) pDC->SetPixelV(x,y,Color);
- if (count>5) {draw=1-draw;count=0;}
- while (e>=0){
- if (interchange==1) x+=s1;else y+=s2;
- e-=dx+dx;
- }
- if (interchange==1) y+=s2; else x+=s1;
- e+=2*dy;
- }
- }
- void SeedFill(CDC *pDC,CPoint seed,COLORREF Color)
- {
- struct NodeType{
- int x;
- int y;
- NodeType *next;
- };
- NodeType *Node,*Tail,*temp;
- COLORREF seedcolor=pDC->GetPixel(seed);
- if (seedcolor==Color) return;
- pDC->SetPixelV(seed,Color);
- Node=new NodeType;
- Tail=Node;
- Node->x=seed.x;
- Node->y=seed.y;
- Node->next=NULL;
- while (Node){
- if (pDC->GetPixel(Node->x+1,Node->y)==seedcolor){
- temp=new NodeType;
- temp->x=Node->x+1;
- temp->y=Node->y;
- Tail->next=temp;
- temp->next=NULL;
- Tail=temp;
- pDC->SetPixelV(temp->x,temp->y,Color);
- }
- if (pDC->GetPixel(Node->x-1,Node->y)==seedcolor){
- temp=new NodeType;
- temp->x=Node->x-1;
- temp->y=Node->y;
- Tail->next=temp;
- temp->next=NULL;
- Tail=temp;
- pDC->SetPixelV(temp->x,temp->y,Color);
- }
- if (pDC->GetPixel(Node->x,Node->y+1)==seedcolor){
- temp=new NodeType;
- temp->x=Node->x;
- temp->y=Node->y+1;
- Tail->next=temp;
- temp->next=NULL;
- Tail=temp;
- pDC->SetPixelV(temp->x,temp->y,Color);
- }
- if (pDC->GetPixel(Node->x,Node->y-1)==seedcolor){
- temp=new NodeType;
- temp->x=Node->x;
- temp->y=Node->y-1;
- Tail->next=temp;
- temp->next=NULL;
- Tail=temp;
- pDC->SetPixelV(temp->x,temp->y,Color);
- }
- temp=Node;
- Node=Node->next;
- delete temp;
- }
- }
- void insertEdge(EdgeType *list, EdgeType *edge)
- {
- EdgeType * p,* q=list;
- p=q->next;
- while(p!=NULL)
- {
- if(edge->xIntersect<p->xIntersect)
- p=NULL;
- else
- { q=p; p=p->next;}
- }
- edge->next=q->next;
- q->next=edge;
- }
- void deleteAfter(EdgeType *q)
- {
- EdgeType * p=q->next;
- q->next=p->next;
- free(p);
- }
- void updateActiveList(int scan, EdgeType *active)
- {
- EdgeType * q=active,*p=active->next;
- while(p)
- if(scan>=p->yUpper)
- {
- p=p->next;
- deleteAfter(q);
- }
- else
- {
- p->xIntersect=p->xIntersect+p->dxPerScan;
- q=p;
- p=p->next;
- }
- }
- void resortActiveList(EdgeType *active)
- {
- EdgeType *q,*p=active->next;
- active->next=NULL;
- while(p)
- {
- q=p->next;
- insertEdge(active,p);
- p=q;
- }
- }
- int yNext(int k, int cnt, PointType *pts)
- {
- int j;
- if((k+1)>(cnt-1))
- j=0;
- else j=k+1;
- while(pts[k].y==pts[j].y)
- if((j+1)>(cnt-1))
- j=0;
- else j++;
- return (pts[j].y);
- }
- void makeEdgeRec(PointType lower, PointType upper, int yComp,
- EdgeType *edge, EdgeType *edges[])
- {
- edge->dxPerScan=(float)(upper.x-lower.x)/(upper.y-lower.y);
- edge->xIntersect=lower.x;
- if(upper.y<yComp)
- edge->yUpper=upper.y-1;
- else edge->yUpper=upper.y;
- insertEdge(edges[lower.y],edge);
- }
- void buildEdgeList(int cnt, PointType *pts, EdgeType *edges[])
- {
- EdgeType * edge;
- PointType v1,v2;
- int i,yPrev=pts[cnt-2].y;
- v1.x=pts[cnt-1].x;
- v1.y=pts[cnt-1].y;
- for(i=0;i<cnt;i++)
- {
- v2=pts[i];
- if(v1.y!=v2.y)
- {
- edge=(EdgeType *)malloc(sizeof(EdgeType));
- if(v1.y<v2.y)
- makeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
- else
- makeEdgeRec(v2,v1,yPrev,edge,edges);
- }
- yPrev=v1.y;
- v1=v2;
- }
- }
- void buildActiveList(int scan, EdgeType *active, EdgeType *edges[])
- {
- EdgeType *p, *q;
- p=edges[scan]->next;
- while(p)
- {
- q=p->next;
- insertEdge(active,p);
- p=q;
- }
- }
- void fillScan(int scan, EdgeType *active)
- {
- EdgeType * p1,*p2;
- int i;
- p1=active->next;
- while(p1)
- {
- p2=p1->next;
- for(i=p1->xIntersect;i<p2->xIntersect;i++)
- MyDC->SetPixelV((int) i,scan,Mycol);
- p1=p2->next;
- }
- }
- void scanFill(CDC *pDC,int cnt, PointType* pts,int Height,COLORREF col)
- {
- EdgeType * active;
- EdgeType * * edges;
- Mycol=col;
- edges=(EdgeType * *)malloc(sizeof(EdgeType*)*Height);
- int i,scan;
- MyDC=pDC;
- for(i=0;i<Height;i++)
- {
- edges[i]=(EdgeType *)malloc(sizeof(EdgeType));
- edges[i]->next=NULL;
- }
- buildEdgeList(cnt,pts,edges);
- active=(EdgeType * )malloc(sizeof(EdgeType));
- active->next=NULL;
- for(scan=0;scan<Height;scan++)
- {
- buildActiveList(scan,active,edges);
- if(active->next)
- {
- fillScan(scan,active);
- updateActiveList(scan,active);
- resortActiveList(active);
- }
- }
- }
- void DrawCircle(CDC *p,int xo,int yo,int r,COLORREF color)
- {
- int xa,ya,l,f;
- xa=xo+r;
- ya=yo;
- l=(int)(r*cos(45*pi/180));
- f=0;
- //对特殊情况的处理
- if(r==0 || r==1 || r==2 || r==3)
- {
- CPen newpen;
- CPen *oldpen;
- newpen.CreatePen(PS_SOLID,1,color);
- oldpen=p->SelectObject(&newpen);
- p->Ellipse(xo-r,yo-r,xo+r,yo+r);
- p->SelectObject(oldpen);
- }
- else{
- while(l>=0)
- {
- //对称的画八个点
- p->SetPixelV(xa,ya,color);
- p->SetPixelV(xa,2*yo-ya,color);
- p->SetPixelV(2*xo-xa,ya,color);
- p->SetPixelV(2*xo-xa,2*yo-ya,color);
- p->SetPixelV(xo+ya-yo,yo+xa-xo,color);
- p->SetPixelV(xo+ya-yo,yo-xa+xo,color);
- p->SetPixelV(xo-ya+yo,yo+xa-xo,color);
- p->SetPixelV(xo-ya+yo,yo-xa+xo,color);
- if(f>=0)
- {
- xa=xa-1;
- f=f-2*(xa-xo)+1;
- }
- else{
- ya=ya-1;
- f=f+2*(yo-ya)+1;
- l--;
- }
- }
- }
- }
- void DrawEllipse(CDC *p,int xo,int yo,int a,int b,COLORREF color)
- {
- int x,y;
- float f;
- if(a==0 || b==0){
- p->SetPixelV(xo,yo,color);
- return;
- }
- else{
- x=0;y=b;
- f=b*b+a*a*(0.25-b);
- while((float)(b*b*(x+1))<=a*a*(y-0.5))
- {
- //对称的画出四个向限的点
- p->SetPixelV(x+xo,yo-y,color);
- p->SetPixelV(x+xo,yo+y,color);
- p->SetPixelV(xo-x,yo-y,color);
- p->SetPixelV(xo-x,yo+y,color);
- if(f<0) {
- f+=(float)(b*b*(2*x+3));
- x++;
- }
- else {
- f+=(float)(b*b*(2*x+3)+2*a*a*(1-y));
- x++;y--;
- }
- }
- f=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*b*a*b;
- while(y>=0)
- {
- //对称的画出四个向限的点
- p->SetPixelV(x+xo,yo-y,color);
- p->SetPixelV(x+xo,yo+y,color);
- p->SetPixelV(xo-x,yo-y,color);
- p->SetPixelV(xo-x,yo+y,color);
- if(f<0) {
- f+=(float)(2*b*b*(x+1)+a*a*(3-2*y));
- x++;y--;
- }
- else {
- f+=a*a*(3-2*y);
- y--;
- }
- }
- }
- return;
- }
- void DrawPipo(CDC *p,int x1,int y1,int x2,int y2,int x3,int y3,COLORREF color)
- {
- int a1,a2,b1,b2,c1,c2;
- int x,y;
- double t,d;
- //计算双曲线的参数
- a1=x1-3*x2+2*x3;
- a2=y1-3*y2+2*y3;
- b1=3*x2-2*x1;
- b2=3*y2-2*y1;
- c1=x1;
- c2=y1;
- t=0.0;
- d=0.0005;
- //t从0到1,步长为0.0005
- while(t<=1.0)
- {
- x=(int)((float)(c1+b1*t+a1*t*t)/(1+t));
- y=(int)((float)(c2+b2*t+a2*t*t)/(1+t));
- p->SetPixelV(x,y,color);
- t+=d;
- }
- }
- COLORREF linecolor=RGB(64,0,0);
- void edgeflagscan(CDC *fl,PointType points[],int n,COLORREF fillcolor)
- {
- int i,j,x,y,xmin,xmax,ymin,ymax;
- int x1,y1,x2,y2,flag=0,already;
- int xarray[50],yarray[50];
- for(i=0;i<=n-1;i++)
- {
- xarray[i]=points[i].x;
- yarray[i]=points[i].y;
- }
- xmax=getmax(xarray,n); //x坐标最大值
- xmin=getmin(xarray,n); //x坐标最小值
- ymax=getmax(yarray,n); //y坐标最大值
- ymin=getmin(yarray,n); //y坐标最小值
- for(i=0;i<=n-1;i++)
- {
- if(points[i].x>points[(i+1)%n].x) j=-1;
- else if(points[i].x<points[(i+1)%n].x) j=1;
- else j=0;
- x1=points[i].x;x2=points[(i+1)%n].x;
- y1=points[i].y;y2=points[(i+1)%n].y;
- for(x=points[i].x;x!=points[(i+1)%n].x;x+=j)
- {
- already=0;
- if(x==points[i].x && x!=points[0].x)
- {
- if((x-points[(i-1+n)%n].x)*(x-points[(i+1)%n].x)>0)
- {
- //对非极值顶点处理:向下移一位
- if(x!=points[n-1].x) fl->SetPixelV(x,y+1,linecolor);
- already=1;
- }
- //对极值顶点处理:略过
- if((x-points[(i-1+n)%n].x)*(x-points[(i+1)%n].x)<0)
- x+=j;
- }
- //对竖直边的处理
- if(x2!=x1) y=(y2-y1)*(x-x1)/(x2-x1)+y1;
- else y=(y1>y2)?y2:y1;
- if(already==0) fl->SetPixelV(x,y,linecolor);
- }
- //对多边形的最后一点补充
- if(x!=points[0].x || i!=n-1) fl->SetPixelV(x,y,linecolor);
- else if(fl->GetPixel(points[0].x,points[0].y)==linecolor)
- fl->SetPixelV(points[0].x,points[0].y+1,linecolor);
- }
- //根据标志来对多边形填色
- for(x=xmin;x<=xmax;x++)
- {
- for(y=ymin;y<=ymax;y++)
- {
- if(fl->GetPixel(x,y)==linecolor)
- flag=(flag+1)%2;
- if(flag==1 && fl->GetPixel(x,y)!=linecolor) fl->SetPixelV(x,y,fillcolor);
- }
- flag=0;
- }
- return;
- }
- ///////////////////判断凹凸性/////////////////////////
- //判断一点在直线的哪侧
- int flag(int x1,int y1,int x2,int y2,int x,int y)
- {
- int d;
- float f;
- f=(float)(y-y1)*(x2-x1)-(float)(y2-y1)*(x-x1);
- if(f==0.0) d=0;
- else if(f>0) d=1;
- else d=-1;
- return d;
- }
- void DecidePolygonUpper(int n,PointType points[])
- {
- if(points==NULL){
- AfxMessageBox("请先画一多边形!");
- return;
- }
- else{
- int dd=0,count=0;
- int s1=0,s2=0;
- for(int i=0;i<=n-1;i++)
- {
- for(int j=0;j<=n-1;j++)
- {
- if(j==i || j==i+1) j++;
- else{
- dd=flag(points[i].x,points[i].y,points[(i+1)%n].x,points[(i+1)%n].y,points[j].x,points[j].y);
- if(dd==1) s1++;
- if(dd==-1) s2++;
- }
- }
- if(s1==n-2 || s2==n-2) count++;
- s1=0;
- s2=0;
- }
- if(count==n)
- {
- AfxMessageBox("凸多边形!");
- }
- else
- {
- AfxMessageBox("凹多边形!");
- }
- return;
- }
- }
English
