[图形学]直线生成算法之DDA
DDA称为数值微分画线算法,是直线生成算法中最简单的一种。原理相当简单,就是最直观的根据斜率的偏移程度,决定是以x为步进方向还是以y为步进方向。然后在相应的步进方向上,步进变量每次增加一个像素,而另一个相关坐标变量则为Yk_1=Yk+m(以x为步进变量为例,m为斜率)
这个程序对于我的意义在于:可以在VC中利用GDI的画点函数--- SetPixel来实现它,终于可以告别C语言绘图还用TC的时代,呵呵~~~
void DDALine(float x1,float y1,float x2,float y2,int color,HDC hdc)
{
float m;
float dx,dy;
float x,y;
x1=(int)(x1+0.5);
y1=(int)(y1+0.5);
x=x1;
y=y1;
dx=x2-x1;
dy=y2-y1;
if(fabs(dx)>=fabs(dy))
m=dy/dx;
else
m=dx/dy;
while(x<=x2)
{
SetPixel(hdc,x,y,color);
if(fabs(dx)>=dy)
{
y=y+m;
x++;
}
else
{
x=x+m;
y++;
}
}
}
VC中的实现:
#include "GraphAlgorithm.h"
#include<windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
long WINAPI WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam);
BOOL InitWindowsClass(HINSTANCE hInstance);
BOOL InitWindows(HINSTANCE hInstance,int nCmdShow);
HWND hWndMain;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
//program starting.
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow)
{
MSG msg;
if(!InitWindowsClass(hInstance))
return FALSE;
if(!InitWindows(hInstance,nCmdShow))
return FALSE;
//Core message looping
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//main wndProc function: message looping
long WINAPI WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hDC;
HBRUSH hBrush;
HPEN hPen;
PAINTSTRUCT PtStr;
switch(iMessage)
{
case WM_PAINT:
//First draw,a black line
hDC=BeginPaint(hWnd,&PtStr);
hPen=(HPEN)GetStockObject(NULL_PEN);//get empty brush
SelectObject(hDC,hPen);
hBrush=(HBRUSH)GetStockObject(BLACK_BRUSH);
SelectObject(hDC,hBrush);
hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));//create pen
SelectObject(hDC,hPen);
DDALine(0,0,200,200,1,hDC);
DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(hWnd,&PtStr);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd,iMessage,wParam,lParam);
}
}
//Init the Window to show out.
BOOL InitWindows(HINSTANCE hInstance,int nCmdShow)
{
HWND hWnd;
hWnd=CreateWindow("WinFill",
"图形绘制算法示例程序",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
NULL
);
if(!hWnd)
return FALSE;
hWndMain=hWnd;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//Set wndClass Propertity
BOOL InitWindowsClass(HINSTANCE hInstance)
{
WNDCLASS wndClass;
wndClass.cbClsExtra=0;
wndClass.cbWndExtra=0;
wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndClass.hIcon=LoadIcon(NULL,"END");
wndClass.hInstance=hInstance;
wndClass.lpfnWndProc=WndProc;
wndClass.lpszClassName="WinFill";
wndClass.lpszMenuName=NULL;
wndClass.style=CS_HREDRAW|CS_VREDRAW;
return RegisterClass(&wndClass);
}
通过测试表明,当斜率较大时,如3以上,出现了些小锯齿.
继续前进!!!