c++画扇形的算法或源代码
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);
}