?? arithmatic.cpp
字號:
/*****************************************************
Arithmatic.C --DDA與Bresenham直線算法演示
四川大學信息學院 許庶 編制
2007.10.01
******************************************************/
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <math.h>
#include <windows.h>
#include <winuser.h>
#include "resource.h"
#include <vector>
using namespace std;
void WindowInitial(HINSTANCE hInstance,HINSTANCE hPrevInstance);
long FAR PASCAL WndProc(HWND,WORD,WORD,LONG);
LRESULT CALLBACK DialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
void DrawDDB(vector <int> nx,vector <int> ny,int num);
void ClearDDB();
void CopyDDB();
void DDA(int dx1,int dy1,int dx2,int dy2);
void BRE(int bx1,int by1,int bx2,int by2);
int Order(int numx,int numy,int p);
void BRESENHAM(int bx1,int by1,int bx2,int by2,float m);
void DrawLine(int Lx1,int Ly1,float dx,float dy,int num);
float sign(int a,int b,float m);
char mx1[5]="0";//直線頂點坐標
char my1[5]="0";
char mx2[5]="0";
char my2[5]="0";
int Width,Height;
HWND Thwnd;
HINSTANCE Thinstance;
HBITMAP hBitmap;
char szAppName[]="Arithmatic";
/*****************************************************
程序函數主入口
******************************************************/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{ Thinstance=hInstance;
MSG msg;
Width=400;
Height=400;
WindowInitial(hInstance,hPrevInstance);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/*****************************************************
主窗口初始化
******************************************************/
void WindowInitial(HINSTANCE hInstance,
HINSTANCE hPrevInstance)
{
HWND hWnd;
WNDCLASS wndclass;
HDC hdc;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = (WNDPROC)WndProc;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass);
}
hdc =GetDC(NULL);
Width =GetDeviceCaps(hdc,HORZRES);
Height =GetDeviceCaps(hdc,VERTRES)-30;
ReleaseDC(NULL,hdc);
hWnd = CreateWindow(szAppName,
"DDA與Bresenham直線算法演示",
WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME,
0,0,
Width,
Height,
NULL,NULL,hInstance,NULL);
Thwnd=hWnd;
ShowWindow(hWnd,SW_MAXIMIZE);
UpdateWindow(hWnd);
ClearDDB();
}
/*****************************************************
對話框消息處理循環
******************************************************/
LRESULT CALLBACK DialogProc(HWND hDlg,UINT message,
WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam)==IDOK )
{
SendDlgItemMessage(hDlg,ID_X1, WM_GETTEXT,5,(LPARAM)mx1);
SendDlgItemMessage(hDlg,ID_Y1, WM_GETTEXT,5,(LPARAM)my1);
SendDlgItemMessage(hDlg,ID_X2, WM_GETTEXT,5,(LPARAM)mx2);
SendDlgItemMessage(hDlg,ID_Y2, WM_GETTEXT,5,(LPARAM)my2);
if( abs(atoi(mx1))>550
||abs(atoi(mx2))>550
||abs(atoi(my1))>400
||abs(atoi(my2))>400
)
{ MessageBox(hDlg,"您輸入的數字過大","提示",MB_OK);
return TRUE;
}
EndDialog(hDlg,TRUE);
return TRUE;
}
break;
}
return FALSE;
}
/*****************************************************
主窗口消息處理循環
******************************************************/
long FAR PASCAL WndProc(HWND hWnd,WORD message,
WORD wParam,LONG lParam)
{
PAINTSTRUCT ps;
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
if(hBitmap)DeleteObject(hBitmap);
break;
case WM_COMMAND:
switch(wParam)
{
case ID_DDA:
DialogBox(Thinstance,MAKEINTRESOURCE(ID_ID),Thwnd,(DLGPROC)DialogProc);
DDA(atoi(mx1),atoi(my1),atoi(mx2),atoi(my2));
return 0;
case ID_Bre:
DialogBox(Thinstance,MAKEINTRESOURCE(ID_ID),Thwnd,(DLGPROC)DialogProc);
BRE(atoi(mx1),atoi(my1),atoi(mx2),atoi(my2));
return 0;
case ID_Me:
MessageBox(hWnd," 四川大學 信息學院 2007 \n\n 許庶","版權信息",MB_OK);
return 0;
}
case WM_PAINT:
BeginPaint(hWnd,&ps);
CopyDDB();
EndPaint(hWnd,&ps);
break;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
/*****************************************************
繪制位圖
******************************************************/
void DrawDDB(vector <int> nx,vector <int> ny,int num)
{
int i;
HDC hDC,hMDC;
hDC=GetDC(Thwnd);
hBitmap=CreateCompatibleBitmap(hDC,Width,Height);
hMDC =CreateCompatibleDC(NULL);
SelectObject(hMDC,hBitmap);
PatBlt(hMDC,0,0,Width,Height,WHITENESS);
TextOut(hMDC,Width/2+7,0,"Y",1);
TextOut(hMDC,Width-20,Height/2-18,"X",1);
for( i=0;i<Width;i++)SetPixel(hMDC,i,Height/2,0xff0000);//繪制X軸
for( i=0;i<Height;i++)SetPixel(hMDC,Width/2,i,0xff0000);//繪制Y軸
for( i=0;i<num;i++)SetPixel(hMDC,nx[i]+Width/2,Height/2-ny[i],0x0000ff);
BitBlt(hDC,0,0,Width,Height,hMDC,0,0,SRCCOPY);
DeleteObject(hMDC);
DeleteDC(hMDC);
ReleaseDC(Thwnd,hDC);
}
/*****************************************************
刷新位圖
******************************************************/
void ClearDDB()
{
HDC hDC,hMDC;
hDC=GetDC(Thwnd);
hBitmap=CreateCompatibleBitmap(hDC,Width,Height);
hMDC =CreateCompatibleDC(NULL);
SelectObject(hMDC,hBitmap);
BitBlt(hDC,0,0,Width,Height,hMDC,0,0,SRCCOPY);
DeleteObject(hMDC);
DeleteDC(hMDC);
ReleaseDC(Thwnd,hDC);
}
/*****************************************************
復制位圖
******************************************************/
void CopyDDB()
{
HDC hDC,hMDC;
hDC=GetDC(Thwnd);
hMDC =CreateCompatibleDC(NULL);
SelectObject(hMDC,hBitmap);
BitBlt(hDC,0,0,Width,Height,hMDC,0,0,SRCCOPY);
DeleteObject(hMDC);
DeleteDC(hMDC);
ReleaseDC(Thwnd,hDC);
}
/*****************************************************
DDA直線
******************************************************/
void DDA(int dx1,int dy1,int dx2,int dy2)
{
float dx,dy;
int numx,numy,num;
float m;
if(dx1!=dx2)m=(float)(dy2-dy1)/(dx2-dx1);
numx=abs(dx1-dx2);
numy=abs(dy1-dy2);
if(dx1==dx2)
{
num=numy;
dx=0;
dy=sign(dy1,dy2,1);
DrawLine(dx1,dy1,dx,dy,num);
}
else if(dy1==dy2)
{
num=numx;
dx=sign(dx1,dx2,1);
dy=0;
DrawLine(dx1,dy1,dx,dy,num);
}
else
{
if(numx>numy)
{
num=numx;
dx=sign(dx1,dx2,1);
dy=dx*m;
DrawLine(dx1,dy1,dx,dy,num);
}
else
{
num=numy;
dy=sign(dy1,dy2,1);
dx=dy*(1/m);
DrawLine(dx1,dy1,dx,dy,num);
}
}
}
void BRE(int bx1,int by1,int bx2,int by2) //Bresenham直線預處理
{
if((bx1==bx2)||(by1==by2))DDA(bx1,by1,bx2,by2);
float m;
int t;
m=(float)(by1-by2)/(bx1-bx2);
if((m==1)||(m==(-1)))DDA(bx1,by1,bx2,by2);
if(m>1)
{
t=by1;by1=bx1;bx1=t;
t=by2;by2=bx2;bx2=t;
BRESENHAM(bx1,by1,bx2,by2,m);
}
if((m<0)&&(m>-1))
{
bx1=-bx1;bx2=-bx2;
BRESENHAM(bx1,by1,bx2,by2,m);
}
if(m<-1)
{
t=by1;by1=-bx1;bx1=t;
t=by2;by2=-bx2;bx2=t;
BRESENHAM(bx1,by1,bx2,by2,m);
}
if(0<m && m<1)
{
BRESENHAM(bx1,by1,bx2,by2,m);
}
}
/*****************************************************
Bresenham直線
******************************************************/
void BRESENHAM(int bx1,int by1,int bx2,int by2,float m)
{
int numx,numy,num;
int p,t;
int dx,dy;
vector <int> Lx;
vector <int> Ly;
numx=abs(bx1-bx2);
numy=abs(by1-by2);
num=numx;
p=2*numy-numx;
dx=1;
if(bx1>bx2)
{
t=bx1;bx1=bx2;bx2=t;
}
for(t=0;t<num;t++)
{
if(p<0)
{
dy=0;
}
else
{
dy=1;
}
p=Order(numx,numy,p);
Lx.push_back(bx1);
Ly.push_back(by1);
bx1+=dx;
by1+=dy;
}
if(m>1)
{
for(t=0;t<num;t++)
{
p=Ly[t];Ly[t]=Lx[t];Lx[t]=p;
}
DrawDDB(Lx,Ly,num);
}
if((m<0)&&(m>-1))
{
for(t=0;t<num;t++)
{
Lx[t]=-Lx[t];
}
DrawDDB(Lx,Ly,num);
}
if(m<-1)
{
for(t=0;t<num;t++)
{
p=Ly[t];Ly[t]=-Lx[t];Lx[t]=p;
}
DrawDDB(Lx,Ly,num);
}
if(0<m && m<1)
{
DrawDDB(Lx,Ly,num);
}
}
float sign(int a,int b,float m)
{
if(a>b)return (-m);//判斷符號
if(a<b)return m;
return 0;
}
void DrawLine(int Lx1,int Ly1,float dx,float dy,int num) //繪制DDA直線
{
float s,t;
int i;
vector <int> Lx;
vector <int> Ly;
s=(float)Lx1;
t=(float)Ly1;
for(i=0;i<num;i++)
{
Lx.push_back(s);
Ly.push_back(t);
s+=dx;
t+=dy;
}
DrawDDB(Lx,Ly,num);
}
int Order(int numx,int numy,int p)
{
if(p>0)
{
p=p+2*numy-2*numx;
}
else
{
p=p+2*numy;
}
return p;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -