第五章 图形基础part2
2009-11-17 16:32
274 查看
5.3画点和线
设定图素:
SetPixel(hdc, x, y, crColor) ;//在指定的x和y坐标以特定的颜色设定图素.最后一个参数是COLORREF型态指定了颜色。
crColor = GetPixel(hdc, x, y) ;//传回指定坐标处的图素颜色
直线:
Windows可以画直线、椭圆线(椭圆圆周上的曲线)和贝塞尔曲线。
MoveToEx(hdc, xBeg, yBeg, NULL) ;//实际上不会画线,它只是设定了设备内容的「目前位置」属性
LineTo(hdc, xEnd, yEnd) ;//从目前的位置到它所指定的点画一条直线
如果在呼叫LineTo之前没有设定目前位置,那么它将从显示区域的左上角开始画线。如果您需要目前位置,就可以通过以下呼叫获得:GetCurrentPositionEx (hdc, &pt) ; pt是POINT结构的。
将数组中的点连接成线时使用Polyline (hdc, apt, 5) ;最后一个参数是点的数目。PolylineTo有些不同,这个函数使用目前位置作为开始点。
SINEWAVE
边界框函数:
画一个矩形Rectangle(hdc, xLeft, yTop, xRight, yBottom);点(xLeft, yTop)是矩形的左上角,(xRight, yBottom)是矩形的右下角。
画椭圆 Ellipse(hdc, xLeft, yTop, xRight, yBottom);
画圆角矩形的函数RoundRect(hdc, xLeft, yTop, xRight, yBottom, xCornerEllipse, yCornerEllipse);
Arc(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Chord(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Pie(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
LINEDEMO
贝塞尔曲线:
贝塞尔曲线的参数方程,起点是(x0,y0),终点是(x3,y3),两个控制点是(x1,y1)和(x2,y2),随着t的值从0到1的变化,
x(t) = (1 - t)3 x0 + 3t (1 - t)2 x1 + 3t2 (1 - t) x2 + t3 x3
y(t) = (1 - t)3 y0 + 3t (1 - t)2 y1 + 3t2 (1 - t) y2 + t3 y3
PolyBezier(hdc, apt, iCount);
PolyBezierTo(hdc, apt, iCount);apt都是POINT结构的数组。对PolyBezier,前四个点(按照顺序)给出贝塞尔曲线的起点、第一个控制点、第二个控制点和终点。
使用现有画笔(Stock Pens):
Windows表头文件WINDEF.H中包含一个叫做HPEN的型态定义,即画笔的句柄。HPEN hPen;呼叫GetStockObject,可以获得现有画笔的句柄。
画笔的建立、选择和删除:使用函数CreatePen或CreatePenIndirect建立一个「逻辑画笔」。
GDI对象有画笔、画刷、位图、区域、字体和调色盘。除了调色盘之外,这些对象都是通过SelectObject选进设备内容的。
在使用画笔等GDI对象时应该注意:
1.最后要删除自己建立的所有GDI对象。
2.当GDI对象正在一个有效的设备内容中使用时,不要删除它。
3.不要删除现有对象。
LOGPEN(「逻辑画笔」)的结构,并呼叫CreatePenIndirect来建立画笔。hPen = CreatePenlndirect(&logpen);
typedef struct tagLOGPEN { kk1}
POINT lopnWidth;
COLORREF lopnColor;
}LOGPEN;
CreatePen和CreatePenIndirect函数不需要设备内容句柄作为参数。这些函数建立与设备内容没有联系的逻辑画笔。 直到呼叫SelectObject之后,画笔才与设备内容发生联系。
填入空隙:
空隙的着色取决于设备内容的两个属性-背景模式和背景颜色。可以通过如下呼叫来改变Windows用来填入空隙的背景色:SetBkColor (hdc, crColor);通过将背景模式转换为TRANSPARENT,可以阻止Windows填入空隙:SetBkMode (hdc, TRANSPARENT);GetBkMode来取得目前背景模式。
BEZIER
设定图素:
SetPixel(hdc, x, y, crColor) ;//在指定的x和y坐标以特定的颜色设定图素.最后一个参数是COLORREF型态指定了颜色。
crColor = GetPixel(hdc, x, y) ;//传回指定坐标处的图素颜色
直线:
Windows可以画直线、椭圆线(椭圆圆周上的曲线)和贝塞尔曲线。
MoveToEx(hdc, xBeg, yBeg, NULL) ;//实际上不会画线,它只是设定了设备内容的「目前位置」属性
LineTo(hdc, xEnd, yEnd) ;//从目前的位置到它所指定的点画一条直线
如果在呼叫LineTo之前没有设定目前位置,那么它将从显示区域的左上角开始画线。如果您需要目前位置,就可以通过以下呼叫获得:GetCurrentPositionEx (hdc, &pt) ; pt是POINT结构的。
将数组中的点连接成线时使用Polyline (hdc, apt, 5) ;最后一个参数是点的数目。PolylineTo有些不同,这个函数使用目前位置作为开始点。
SINEWAVE
#include <windows.h> #include <math.h> #define NUM 1000 #define TWOPI (2 * 3.14159) LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("SineWave") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; 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 = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass (&wndclass)) { MessageBox(NULL, TEXT ("Program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow( szAppName, TEXT ("Sine Wave Using Polyline"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 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) { static int cxClient, cyClient ; HDC hdc ; int i ; PAINTSTRUCT ps ; POINT apt [NUM] ; switch (message) { case WM_SIZE: //当前窗口的大小 cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps); //设定了设备内容的「目前位置」属性,这里设定为当前窗口的一半 MoveToEx(hdc, 0, cyClient / 2, NULL); LineTo(hdc, cxClient, cyClient / 2); //画直线 for (i = 0 ; i < NUM ; i++) { //结构的x成员设定为从0递增到数值cxClient apt[i].x = i * cxClient / NUM; //结构的y成员设定为一个周期的正弦曲线值,并被放大以填满显示区域。 apt[i].y = (int) (cyClient / 2 * (1 - sin(TWOPI * i / NUM))); } //将数组中的点连接成线,这个函数使用目前位置作为开始点 Polyline(hdc, apt, NUM); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
边界框函数:
画一个矩形Rectangle(hdc, xLeft, yTop, xRight, yBottom);点(xLeft, yTop)是矩形的左上角,(xRight, yBottom)是矩形的右下角。
画椭圆 Ellipse(hdc, xLeft, yTop, xRight, yBottom);
画圆角矩形的函数RoundRect(hdc, xLeft, yTop, xRight, yBottom, xCornerEllipse, yCornerEllipse);
Arc(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Chord(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Pie(hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
LINEDEMO
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("LineDemo") ; HWND hwnd; MSG msg; WNDCLASS wndclass; 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= (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName= szAppName; if (!RegisterClass (&wndclass)) { MessageBox(NULL, TEXT ("Program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT ("Line Demonstration"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 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) { static int cxClient, cyClient ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0 ; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); //矩形 Rectangle(hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8); //两条贯穿直线 MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, cxClient, cyClient); MoveToEx(hdc, 0, cyClient, NULL); LineTo(hdc, cxClient, 0); //画椭圆 Ellipse(hdc,cxClient / 8,cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8); //画圆角 RoundRect(hdc, cxClient/4, cyClient/4, 3 * cxClient / 4, 3 * cyClient / 4, cxClient / 8, cyClient / 8) ; EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
贝塞尔曲线:
贝塞尔曲线的参数方程,起点是(x0,y0),终点是(x3,y3),两个控制点是(x1,y1)和(x2,y2),随着t的值从0到1的变化,
x(t) = (1 - t)3 x0 + 3t (1 - t)2 x1 + 3t2 (1 - t) x2 + t3 x3
y(t) = (1 - t)3 y0 + 3t (1 - t)2 y1 + 3t2 (1 - t) y2 + t3 y3
PolyBezier(hdc, apt, iCount);
PolyBezierTo(hdc, apt, iCount);apt都是POINT结构的数组。对PolyBezier,前四个点(按照顺序)给出贝塞尔曲线的起点、第一个控制点、第二个控制点和终点。
使用现有画笔(Stock Pens):
Windows表头文件WINDEF.H中包含一个叫做HPEN的型态定义,即画笔的句柄。HPEN hPen;呼叫GetStockObject,可以获得现有画笔的句柄。
画笔的建立、选择和删除:使用函数CreatePen或CreatePenIndirect建立一个「逻辑画笔」。
GDI对象有画笔、画刷、位图、区域、字体和调色盘。除了调色盘之外,这些对象都是通过SelectObject选进设备内容的。
在使用画笔等GDI对象时应该注意:
1.最后要删除自己建立的所有GDI对象。
2.当GDI对象正在一个有效的设备内容中使用时,不要删除它。
3.不要删除现有对象。
LOGPEN(「逻辑画笔」)的结构,并呼叫CreatePenIndirect来建立画笔。hPen = CreatePenlndirect(&logpen);
typedef struct tagLOGPEN { kk1}
POINT lopnWidth;
COLORREF lopnColor;
}LOGPEN;
CreatePen和CreatePenIndirect函数不需要设备内容句柄作为参数。这些函数建立与设备内容没有联系的逻辑画笔。 直到呼叫SelectObject之后,画笔才与设备内容发生联系。
填入空隙:
空隙的着色取决于设备内容的两个属性-背景模式和背景颜色。可以通过如下呼叫来改变Windows用来填入空隙的背景色:SetBkColor (hdc, crColor);通过将背景模式转换为TRANSPARENT,可以阻止Windows填入空隙:SetBkMode (hdc, TRANSPARENT);GetBkMode来取得目前背景模式。
BEZIER
#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("Bezier") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; 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= (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName= NULL ; wndclass.lpszClassName= szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("Program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Bezier Splines"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } void DrawBezier (HDC hdc, POINT apt[]) { PolyBezier(hdc, apt, 4); //两根引导线 MoveToEx(hdc, apt[0].x, apt[0].y, NULL); LineTo(hdc, apt[1].x, apt[1].y); MoveToEx(hdc, apt[2].x, apt[2].y, NULL); LineTo(hdc, apt[3].x, apt[3].y); } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static POINT apt[4] ; HDC hdc ; int cxClient, cyClient ; PAINTSTRUCT ps ; switch (message) { case WM_SIZE: cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); //起点 apt[0].x = cxClient / 4; apt[0].y = cyClient / 2; //两个控制点 apt[1].x = cxClient / 2; apt[1].y = cyClient / 4; apt[2].x = cxClient / 2; apt[2].y = 3 * cyClient / 4; //终点 apt[3].x = 3 * cxClient / 4; apt[3].y = cyClient / 2; return 0; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MOUSEMOVE: //鼠标左键被按下或者鼠标右键被按下 if (wParam & MK_LBUTTON || wParam & MK_RBUTTON) { hdc = GetDC(hwnd); //选择了一个画笔对象 //因为是白色的线,所以作用是销去先前的线 HPEN hPenOld; hPenOld = CreatePen(PS_SOLID,3,RGB(255,255,255)); SelectObject(hdc, hPenOld/*GetStockObject(WHITE_PEN)*/); DrawBezier(hdc, apt); DeleteObject(hPenOld); //鼠标左键控制第一个控制点 if (wParam & MK_LBUTTON) { apt[1].x = LOWORD(lParam); apt[1].y = HIWORD(lParam); } //鼠标右键控制第二个控制点 if (wParam & MK_RBUTTON) { apt[2].x = LOWORD(lParam); apt[2].y = HIWORD(lParam); } //画鼠标变更后的线 HPEN hPen; hPen = CreatePen(PS_SOLID,3,RGB(128,128,128)); SelectObject(hdc, hPen/*GetStockObject(BLACK_PEN)*/); //画贝塞尔曲线 DrawBezier(hdc, apt); DeleteObject(hPen); ReleaseDC(hwnd, hdc); } return 0; case WM_PAINT: InvalidateRect(hwnd, NULL, TRUE); hdc = BeginPaint(hwnd, &ps); DrawBezier(hdc, apt); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0 ; } return DefWindowProc(hwnd, message, wParam, lParam); }
相关文章推荐
- 第五章 图形基础part1
- windows程序设计第五章 图形基础
- 第五章 图形基础part4
- 第五章 图形基础part3
- 第五章 图形基础
- 第五章--图形基础--设备内容(1)
- 3D数学基础及图形与游戏开发的学习 (一)
- 3D数学基础 图形与游戏开发的学习 (六)[多坐标系]
- SVG.js 基础图形绘制整理(二)
- Java核心技术I——基础点拾掇(第五章)
- OpenGL基础图形编程 - OpenGL概念建立
- OpenGL基础图形编程 - 特殊光处理
- Java中的基础构建模块(第五章)
- SQL基础第五章通过视图修改数据
- Unity3D 计算机3D图形基础在Unity中的实现(Vector3,Maxtrix4*4,Transform)
- 基础练习 字母图形
- 回归基础—rrdtool图形命令
- 关于图形的一些基础知识
- 第五章:基础题目选解。第二部分
- java基础08 双重循环打印图形