還記得在 Graph 繪製圖形 這一篇裡,為了畫一個圓而第一次接觸到了畫圓弧的函式,
Arc(HDC hdc, int nLeftRect, int nTopRect, int RightRect, int nBottomRect,
int nXStartArc, int nYStartArc, int nXEndArc, nYEndArc),
雖然只要把nXEndArc﹦nXStartArc,nYEndArc﹦nYStartArc就可以得到我想要的圓,但要怎樣使用nXEndArc、nXStartArc、nYEndArc、﹦nYStartArc來控制圓弧的位置,卻一直摸索不出來。
而又在 繪製圖形中的實線、虛線與線寬 這一篇裡再次地畫了一個圓,這次刻意的將nXEndArc、nXStartArc、nYEndArc、nYStartArc通通改為0來測試一下,
Arc(hdc,230,180,250,200,0,0,0,0),畫圓沒問題,但還是沒能搞懂nXEndArc、nXStartArc、nYEndArc、nYStartArc,我一直認為圓弧也是二元二次方程式,起點與終點的X、Y座標的變化該如何精準的填上呢?
因此,假設整個圓弧是繞著圓心在走的,所以何不加一條輔助線,從圓心拉到起點和終點來看看會發生甚麼事情,就定義兩組座標取任意值
int nXStartArc = 150;
int nYStartArc = 380;
int nXEndArc = 120;
int nYEndArc = 260;
這兩組座標每次執行完後都再更改過數值,再編譯再執行,看看他的變化
定義好兩種顏色的畫筆,比較好區分起點與終點
hpen = CreatePen(PS_SOLID,1,RGB(0,0,0));
hpen1 = CreatePen(PS_SOLID,1,RGB(0,100,255));
畫上輔助線
SelectObject(hdc,hpen);
MoveToEx(hdc,280,280,NULL);
LineTo(hdc,nXStartArc,nYStartArc);
SelectObject(hdc,hpen1);
MoveToEx(hdc,280,280,NULL);
LineTo(hdc,nXEndArc,nYEndArc);
看看設計這個畫圓弧的函式的人當初是怎麼想的,幾趟的重複編譯執行下來總該有個譜吧!
。,、'﹕︰﹔﹖﹑•!?!﹪%*﹡﹢ 我是可愛的分隔線 〈〉『』〖〗[]《》〔〕 「」【】﹁﹃︻﹂﹄︼
main.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define IDM_Demo1 1001
#define IDM_Bottom 1002 //
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
char szAppName[] = "HelloWin";
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof(WNDCLASSEX) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE); //3DFACE);
wndclass.lpszMenuName = "DODO";
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = 0 ;
RegisterClassEx (&wndclass);
hwnd = CreateWindowEx (
0,
szAppName,
"Graph 繪製圖形",
WS_OVERLAPPEDWINDOW,
0,0,800,500,
NULL,
NULL,
hInstance,
NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HPEN hpen, hpen1;
int nXStartArc = 150;
int nYStartArc = 380;
int nXEndArc = 120;
int nYEndArc = 260;
switch (message)
{
HDC hdc;
case WM_PAINT:
hpen = CreatePen(PS_SOLID,1,RGB(0,0,0));
hpen1 = CreatePen(PS_SOLID,1,RGB(0,100,255));
// hdc = GetDC(hwnd);
hdc = BeginPaint(hwnd,&ps); // 若改用這樣則不會閃爍 //*
SelectObject(hdc,hpen1);
MoveToEx(hdc,270,280,NULL); //畫圓心
LineTo(hdc,290,280); //畫圓心
MoveToEx(hdc,280,270,NULL); //畫圓心
LineTo(hdc,280,290); //畫圓心
SelectObject(hdc,hpen);
Arc(hdc,220,220,340,340,0,0,0,0); // 這是畫一個圓
SelectObject(hdc,hpen1);
Arc(hdc,210,210,350,350,nXStartArc,nYStartArc,nXEndArc,nYEndArc); // 這是畫圓弧
SelectObject(hdc,hpen);
MoveToEx(hdc,280,280,NULL); //畫輔助線
LineTo(hdc,nXStartArc,nYStartArc);
SelectObject(hdc,hpen1);
MoveToEx(hdc,280,280,NULL);
LineTo(hdc,nXEndArc,nYEndArc);
// ReleaseDC(hwnd,hdc);
EndPaint(hwnd,&ps); // 若改用這樣則不會閃爍 //*
return 0;
case WM_CREATE:
return 0 ;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_Demo1:
break;
case IDM_Bottom: //
{
InvalidateRect(hwnd, NULL, TRUE);
}
break;
}
return 0 ;
case WM_DESTROY:
DeleteObject(hpen); //不用畫筆時 記得要刪除
DeleteObject(hpen1); //不用畫筆時 記得要刪除
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
延伸閱讀