⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arithmatic.cpp

📁 学习直线算法DDA与Bresenham算法的源程序
💻 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 + -