c++画扇形的算法或源代码

c++画扇形的算法或源代码

楼主wkoe7810(wkoe) 2002-02-09 11:39:33 在 VC/MFC / 图形处理/算法 提问

100分求c++画扇形的算法或源代码,up者有分 问题点数:100、回复次数:16Top

1 楼strip(阿飞 - Mozilla●CSDN●痛)回复于 2002-02-09 11:56:42 得分 0

zgTop

2 楼oldparanoia(paranoia)回复于 2002-02-09 12:37:10 得分 0

有现成的API,  
  Pie  
  The   Pie   function   draws   a   pie-shaped   wedge   bounded   by   the   intersection   of   an   ellipse   and   two   radials.   The   pie   is   outlined   by   using   the   current   pen   and   filled   by   using   the   current   brush.    
   
  BOOL   Pie(  
      HDC   hdc,                   //   handle   to   device   context  
      int   nLeftRect,       //   x-coord   of   bounding   rectangle's   upper-left   corner  
      int   nTopRect,         //   y-coord   of   bounding   rectangle's   upper-left   corner  
      int   nRightRect,     //   x-coord   of   bounding   rectangle's   lower-right   corner  
      int   nBottomRect,   //   y-coord   of   bounding   rectangle's   lower-right   corner  
      int   nXRadial1,       //   x-coord   of   first   radial's   endpoint  
      int   nYRadial1,       //   y-coord   of   first   radial's   endpoint  
      int   nXRadial2,       //   x-coord   of   second   radial's   endpoint  
      int   nYRadial2         //   y-coord   of   second   radial's   endpoint  
  );  
     
  具体用法自己看MSDN吧  
  别忘了给分哦   ^_^  
  Top

3 楼wkoe7810(wkoe)回复于 2002-02-09 12:48:43 得分 0

to   oldparanoia(paranoia)    
      就是因为不能调用现成的api函数,时要自己开一块内存画的Top

4 楼oldparanoia(paranoia)回复于 2002-02-09 13:06:46 得分 0

ft,那你这就不是VC的问题了,而是图形学的问题,hoho  
  但是我还是不明白,你要做什么?需要自己画?Top

5 楼NowCan(城市浪人)回复于 2002-02-09 13:39:16 得分 0

我还是不明白为什么要自己画?你在学图形学吗?Top

6 楼wkoe7810(wkoe)回复于 2002-02-09 13:57:13 得分 0

和图形学差不多拉,不过我的书上没有相关画扇形的部分Top

7 楼wkoe7810(wkoe)回复于 2002-02-09 14:00:31 得分 0

wkoe@sina.com  
  Top

8 楼formula(方程式)回复于 2002-02-09 14:38:30 得分 0

扇形只是圆形的一部分,下面是(基于三角函数)画圆的公式,其中(x0,y0)为圆心、r为半径,a为角度,a由0至360度(2pi)为一个圆。  
  x=x0+r*cos(a)  
  y=y0+r*sin(a)  
   
  Top

9 楼wkoe7810(wkoe)回复于 2002-02-09 15:02:20 得分 0

有现成的c++算法吗  
  Top

10 楼formula(方程式)回复于 2002-02-09 21:46:09 得分 60

 
  根据x=x0+r*cos(a)   y=y0+r*sin(a)  
   
  可以使用CDC::MoveTo   和   CDC::LineTo   函数就可以画出空心的扇形  
   
  ......  
  a=0;   pi=3.1415926;  
  x=x0+r*cos(a);  
  y=y0+r*sin(a);  
  pDC->MoveTo(x0,y0);  
  pDC->LineTo(x,y);  
  for   (a=1;a<=90;a++)  
  {  
      x=x0+r*cos(a*pi/180);  
      y=y0+r*sin(a*pi/180);  
      pDC->MoveTo(x,y);  
  }  
  pDC->LineTo(x0,y0);  
  ......  
   
  当然,a的步长越少圆弧画得越精确,随便写的,你自己试试看。  
  Top

11 楼congling(congling)回复于 2002-02-09 23:06:41 得分 0

画直线/圆/椭圆/扇形等常用操作肯定不能连续使用Cos/Sin等爆慢的函数,我记得计算机图形学中有专门的算法去画的。Top

12 楼wkoe7810(wkoe)回复于 2002-02-10 09:54:28 得分 0

要是自己开出一块内存来画呢Top

13 楼NowCan(城市浪人)回复于 2002-02-10 18:31:58 得分 0

那是用极坐标的方法,关键在于那个步长怎么选。可惜我也没学过图形学。Top

14 楼strip(阿飞 - Mozilla●CSDN●痛)回复于 2002-02-10 18:56:05 得分 0

同意congling(congling)  
  我原先写过,可是那是大学学图示学的时候,源代码在那个坏了的200M的硬盘上  
  :((Top

15 楼congling(congling)回复于 2002-02-12 06:16:22 得分 20

计算机椭圆的算法  
   
  F(x,y)=b^2*x^2+a^2*y^2-a^2*b^2=0是椭圆的方程  
  如果F(x,y)<=0,我们认为点在椭圆的内部,F(x,y)>0,我们认为点在椭圆的外部。  
  但是F(x,y)的计算量是3次方的计算量(B*x*x),为了简化计算量,我们使用递推法,  
  F(i+1)=F(i)+dF  
   
  我们先对第一象限的部分进行讨论  
  对于(x,y)下一个点,有(x+1,y),(x,y-1),(x+1,y-1)三种情况可供选择。  
   
   
  1)-1<dy/dx<0   ->   0<b^2*x/(a^2*y)<1   ->   b^2*x<a^2*y  
  可以看出y的减少率没有x增长率高,我们应该增加x来看y的增长,于是排除(x,y-1)的可能。  
  如果F(x,y)<=0,对于下一个点我们应该尽量向外推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i),dF=2*b^2*x+b^2  
  如果F(x,y)>0,对于下一个点我们应该尽量向内推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i)-1,dF=2*b^2*x+b^2-2*a^2*y+a^2  
  2)dy/dx>=-1   ->   b^2*x>=a^2*y  
  可以看出y的减少率比x增长率高,我们应该减少y来看x的增长,于是排除(x+1,y)的可能。  
  如果F(x,y)<=0,对于下一个点我们应该尽量向外推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i)-1,dF=2*b^2*x+b^2-2*a^2*y+a^2  
  如果F(x,y)>0,对于下一个点我们应该尽量向内推,因此  
  x(i+1)=x(i),y(i+1)=y(i)-1,dF=-2*a^2*y+a^2  
   
  通过第一象限可以画出其他的象限,当然如果画弧,就要先算好初始的值,然后根据不同的角度在不同象限的表现,进行画图。Top

16 楼congling(congling)回复于 2002-02-12 09:13:33 得分 20

#include   <windows.h>  
  #include   <math.h>  
  #include   "resource.h"  
  /*  
  Ellipse:  
  1)-1<dy/dx<0   ->   0<b^2*x/(a^2*y)<1   ->   b^2*x<a^2*y  
  可以看出y的减少率没有x增长率高,我们应该增加x来看y的增长,于是排除(x,y-1)的可能。  
  如果F(x,y)<=0,对于下一个点我们应该尽量向外推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i),dF=2*b^2*x+b^2  
  如果F(x,y)>0,对于下一个点我们应该尽量向内推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i)-1,dF=2*b^2*x+b^2-2*a^2*y+a^2  
  2)dy/dx>=-1   ->   b^2*x>=a^2*y  
  可以看出y的减少率比x增长率高,我们应该减少y来看x的增长,于是排除(x+1,y)的可能。  
  如果F(x,y)<=0,对于下一个点我们应该尽量向外推,因此  
  x(i+1)=x(i)+1,y(i+1)=y(i)-1,dF=2*b^2*x+b^2-2*a^2*y+a^2  
  如果F(x,y)>0,对于下一个点我们应该尽量向内推,因此  
  x(i+1)=x(i),y(i+1)=y(i)-1,dF=-2*a^2*y+a^2  
   
  */  
   
  #define   G(x,y)   b*b*x*x+a*a*y*y-a*a*b*b  
   
  void   DrawPixelPart(HDC   hdc,int   x0,int   y0,int   x,int   y,int   part,COLORREF   color)  
  {  
  switch(part)  
  {  
  case   0:  
  SetPixel(hdc,x0-x,y0-y,color);break;  
  case   1:  
  SetPixel(hdc,x0+x,y0-y,color);break;  
  case   2:  
  SetPixel(hdc,x0+x,y0+y,color);break;  
  case   3:  
  SetPixel(hdc,x0-x,y0+y,color);break;  
  default:  
  break;  
  }  
  }  
  #define   PI   3.14159  
  void   DrawArcPart(HDC   hdc,int   x0,int   y0,int   a,int   b,int   arc_start,int   arc_end,int   part,COLORREF   color)  
  {  
  int   F,x,y,B=b*b,A=a*a,Bx,Ay,xend,yend;  
  x=((double)a)*sin(arc_start*PI/180)+0.5;y=((double)b)*cos(arc_start*PI/180)+0.5;  
  xend=((double)a)*sin(arc_end*PI/180)+0.5;yend=((double)b)*cos(arc_end*PI/180)+0.5;  
  xend=max(xend,x);yend=min(yend,y);  
  Bx=B*x;Ay=A*y;  
  F=G(x,y);  
  while(Bx<Ay&&x<=xend&&y>=yend)  
  {  
  DrawPixelPart(hdc,x0,y0,x,y,part,color);  
  if(F>0)  
  {  
  x++;y--;F+=2*Bx+B-2*Ay+A;Bx+=B;Ay-=A;  
  }  
  else  
  {  
  x++;F+=2*Bx+B;Bx=B*x;Bx+=B;  
  }  
  }  
  if(Bx>=Ay)  
  {  
  while(x<=xend&&y>=yend)  
  {  
  DrawPixelPart(hdc,x0,y0,x,y,part,color);  
  if(F>0)  
  {  
  y--;F+=A-2*Ay;Ay-=A;  
  }  
  else  
  {  
  x++;y--;F+=2*Bx+B-2*Ay+A;Bx+=B;Ay-=A;  
  }  
  }  
  }  
  }  
   
  #define   DrawPart(arc_start,arc_end,part)   DrawArcPart(hdc,x0,y0,a,b,arc_start,arc_end,part,color)  
   
  //用Bresenham算法生成的椭圆弧线,(x0,y0)为圆心,a为x截距,b为y截距,arc_start和arc_end使用角度表示,从-x旋转分别是角度开始/结束,color是颜色  
  void   DrawArc(HDC   hdc,int   x0,int   y0,int   a,int   b,int   arc_start,int   arc_end,COLORREF   color)  
  {  
  int   i,part_start,part_end;  
  if(arc_start>arc_end)//保证arc_end>arc_start  
  {  
  i=arc_start;  
  arc_start=arc_end;  
  arc_end=i;  
  }  
  if(arc_end-arc_start>=360)//两个角差别大于360,就是全画  
  {  
  DrawPart(0,90,0);  
  DrawPart(0,90,1);  
  DrawPart(0,90,2);  
  DrawPart(0,90,3);  
  return;  
  }  
  arc_start%=360;arc_end%=360;  
  part_start=arc_start/90;part_end=arc_end/90;  
  if(arc_start>arc_end)//后接式  
  {  
  if(part_start%2)//偶数象限  
  DrawPart(arc_start%90,90,part_start);  
  else  
  DrawPart(90-arc_start%90,90,part_start);  
   
   
  for(i=part_start+1;i<4;i++)  
  DrawPart(0,90,i);  
   
  if(part_end%2)//偶数象限  
  DrawPart(0,arc_end%90,part_end);  
  else  
  DrawPart(90-arc_end%90,90,part_end);  
   
  for(i=0;i<part_end;i++)  
  DrawPart(0,90,i);  
  }  
  else//前置  
  {  
  if(part_end!=part_start)//不在一个象限  
  {  
  if(part_start%2)//偶数象限  
  DrawPart(arc_start%90,90,part_start);  
  else  
  DrawPart(0,90-arc_start%90,part_start);  
   
   
  if(part_end%2)//偶数象限  
  DrawPart(0,arc_end%90,part_end);  
  else  
  DrawPart(90-arc_end%90,90,part_end);  
   
  for(i=part_start+1;i<part_end;i++)  
  DrawPart(0,90,i);  
  }  
  else  
  DrawPart(arc_start%90,arc_end%90,part_start);  
  }  
  }  
   
   
  INT_PTR   CALLBACK   DialogProc(  
      HWND   hwndDlg,     //   handle   to   dialog   box  
      UINT   uMsg,           //   message  
      WPARAM   wParam,   //   first   message   parameter  
      LPARAM   lParam     //   second   message   parameter  
  )  
  {  
          HANDLE   hdc;  
          PAINTSTRUCT   ps;  
   
  switch(uMsg)  
  {  
  case   WM_PAINT:  
                  hdc=BeginPaint(hwndDlg,&ps);  
  DrawArc(hdc,100,50,70,40,0,150,RGB(255,0,0));  
   
                  EndPaint(hwndDlg,&ps);  
  return   TRUE;  
  case   WM_COMMAND:  
  switch(   LOWORD(wParam))  
  {  
  case   IDOK:  
  case   IDCANCEL:  
  EndDialog(hwndDlg,0);  
  return   TRUE;  
  }  
  break;  
  default:  
  break;  
  }  
  return   FALSE;  
  }  
   
  int   WINAPI   WinMain(  
      HINSTANCE   hInstance,             //   handle   to   current   instance  
      HINSTANCE   hPrevInstance,     //   handle   to   previous   instance  
      LPSTR   lpCmdLine,                     //   command   line  
      int   nCmdShow                             //   show   state  
  )  
  {  
  DialogBox(hInstance,MAKEINTRESOURCE   (IDD_DIALOG1),NULL,DialogProc);  
   
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值