AngleArc函数是通过角度来画圆弧,注意是正圆的弧,而不是椭圆的弧。当然如果指定的角度为360度,画出来的就是圆了。这是一个非常有用的函数,但这个函数多了一条线段,使许多人达不到自己想要的结果,初学者都改用前面章节介绍过的方法来实现。
下面是AngleArc函数的原型,由结果图可以看出,除了弧线之外多了一条线。这条线段是从画笔位置到开始角度在圆周的位置。注意:画笔位置并不是鼠标位置。程序中开始角度为30度。
BOOL AngleArc( HDC hdc, //HDCint
X, //圆心x座标int
Y, //圆心y座标 DWORD dwRadius, //半径 FLOAT eStartAngle, //弧线的开始角度 FLOAT eSweepAngle //弧线经过的角度。注意:不是终止角度 );
LONG clsCur;bool
bDrawing =false
; //画图状态为true POINTS start, end, prev; //开始点、结束点、前一个移动点 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {switch
(message) { //与上例相同,省略 }return
0; } //求半径 double cal(POINTS beg, POINTS end) {double
x, y; DWORD r; //半径 x = end.x - beg.x, y = end.y - beg.y; r = (DWORD)sqrt(x * x + y * y);return
r; } //用AngleArc函数画弧线 void doDraw(HDC hdc, POINTS beg, POINTS end) { DWORD r; //半径float
angle = 30; r = (DWORD)cal(beg, end); AngleArc(hdc, beg.x, beg.y, r, angle, 270);return
; } void Draw(HDC hdc, POINTS beg, POINTS end) { SetROP2(hdc, R2_NOT); //设置前景配色方式为象素反转 doDraw(hdc, beg, end);return
; } void Draw2(HDC hdc, POINTS beg, POINTS end) { HPEN hPen, hOldPen; SetROP2(hdc, R2_COPYPEN); //设置前景配色方式为画笔颜色 hPen = CreatePen(PS_SOLID, 5, RGB(0, 100, 255)); //兰色实线画笔 hOldPen = (HPEN)SelectObject(hdc, hPen); SetROP2(hdc, R2_COPYPEN); //设置前景配色方式 doDraw(hdc, beg, end); SelectObject(hdc, hOldPen); DeleteObject(hPen);return
; }
要消除这个线段很简单,只要在画图前先用MoveToEx()函数将画笔移动到开始角度在圆周上的位置就可以了。那么,圆周上的开始点座标如何确定呢?
圆周上的开始点,根据开始点的角度,相对于圆心的x座标为:“半径×余弦”;相对于圆心的y座标为:“半径×正弦”。然后再加上圆心座标便可以了。注意:sin()函数、cos()函数用的是极座标度数,极座标度数 = 普通度数×PI÷180。
#define
RADIAN 3.1415926/180.0 //用AngleArc函数画弧线 void doDraw(HDC hdc, POINTS beg, POINTS end) { DWORD r; //半径float
angle = 30; r = (DWORD)cal(beg, end); MoveToEx(hdc, (int
)(beg.x + r * cos(angle * RADIAN)), (int
)(beg.y - r * sin(angle * RADIAN)), NULL); AngleArc(hdc, beg.x, beg.y, r, angle, 270);return
; }
在画图前将画笔位置移动到弧线的终止位置,注意终止位置的角度是“开始角度”加上“弧线经过角度”。
void doDraw(HDC hdc, POINTS beg, POINTS end) { DWORD r; //半径float
angle = 30; r = (DWORD)cal(beg, end); MoveToEx(hdc, (int
)(beg.x + r * cos((angle + 270) * RADIAN)), (int
)(beg.y - r * sin((angle + 270) * RADIAN)), NULL); AngleArc(hdc, beg.x, beg.y, r, angle, 270);return
; }
在画图前将画笔位置移动到圆心位置,AngleArc函数会自动画一条圆心到弧线的开始点的线段,画完后画笔停在弧线的终止位置,这时只要再画一条直线到圆心便可以了。
void doDraw(HDC hdc, POINTS beg, POINTS end) { DWORD r; //半径float
angle = 30; r = (DWORD)cal(beg, end); MoveToEx(hdc, beg.x, beg.y, NULL); AngleArc(hdc, beg.x, beg.y, r, angle, 270); LineTo(hdc, beg.x, beg.y);return
; }