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

📄 paintobj.cpp

📁 这是书上的代码
💻 CPP
字号:
// paintobj.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "const.h"
#include "painted.h"
#include "paintobj.h"
#include "mainfrm.h"
#include "paintdoc.h"
#include "SearchPath.h"
#include "SearchNode.h"
#include "paintvw.h"
#include "math.h"
#include "ChildFrame.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPaintobjApp

BEGIN_MESSAGE_MAP(CPaintobjApp, CWinApp)
	//{{AFX_MSG_MAP(CPaintobjApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
	// Standard print setup command
	ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPaintobjApp construction

CPaintobjApp::CPaintobjApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CPaintobjApp object

CPaintobjApp theApp;
double fxmin=0;
double fymin=0;
double m_xstart=0;
double m_ystart=0;
double fxmax=5;
double fymax=5;
int m_wscreen=0;//客户区宽度(逻辑坐标)
int m_hscreen=0;//客户区高度(逻辑坐标)
double fscale=1.0f;
double fbasicscale=0.01f;//表示1像素代表多少米(m/像素)
void DPtoVP(CPnt pnt,CPoint& point)//把最终实际坐标变换为用于显示的逻辑坐标
{
	point.x=(UINT)	((pnt.x-m_xstart)*fscale/fbasicscale);
	point.y=(UINT)	((m_hscreen-(pnt.y-m_ystart)/fbasicscale)*fscale);
}

void DPtoVPf(CPnt pnt,CPnt& point)//把最终实际坐标变换为用于显示的逻辑坐标
{
	point.x=((pnt.x-m_xstart)*fscale/fbasicscale);
	point.y=((m_hscreen-(pnt.y-m_ystart)/fbasicscale)*fscale);
}
void DPtoVP1(double length,int& length1)//把实际长度变换为用于显示的逻辑长度
{			
	length1=int(length*fscale/fbasicscale);
}

void VPtoDP(CPoint point,CPnt& pnt)//从鼠标得到的逻辑坐标变换为用于保存的最终实际坐标
{
	pnt.x=(double)(m_xstart+point.x*fbasicscale/fscale);
    pnt.y=(double)(m_ystart+(m_hscreen-point.y/fscale)*fbasicscale);
}
double Distance(int x1, int y1, int x2, int y2)
{
	return (double)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double Distancef(double x1, double y1, double x2, double y2)
{
	return (double)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
//计算点到直线的垂直距离
//p1即直线外一点
//p2为直线上一点
//p3,p4用于确定直线的斜率
//bbb==FALSE表示p3,p4直接可以确定直线的斜率
//bbb==TRUE表示p3,p4确定的斜率为直线的斜率-1/K
//函数返回计算得到的距离值
double PointToLine1(CPnt p1,CPnt p2,CPnt p3,CPnt p4,BOOL bbb)
{
	double x1,y1,x2,y2,x3,y3,x4,y4,aa;
	x1=p1.x; y1=p1.y;	
	x2=p2.x; y2=p2.y;	
	x3=p3.x; y3=p3.y;	
	x4=p4.x; y4=p4.y;
	CPnt joinpnt;//直线与过p1点的垂线的交点
	if(!bbb)//直接可以确定直线的斜率
	{
		if(fabs(x4-x3)<mindouble)//直线垂直
		{	joinpnt.x=x2;
			joinpnt.y=y1;
		}
		else if(fabs(y4-y3)<mindouble)//直线水平
		{	joinpnt.x=x1;
			joinpnt.y=y2;
		}
		else 
		{
			double k1=(y4-y3)/(x4-x3);
			double k2=(x3-x4)/(y4-y3);							
			joinpnt.x=(double) ((y1-y2+k1*x2-k2*x1)/(k1-k2));
			joinpnt.y=(double) (k1*(joinpnt.x-x2)+y2);
		}	
	}
	else//间接确定直线的斜率
	{
		if(fabs(y4-y3)<mindouble)//直线垂直
		{	joinpnt.x=x2;
			joinpnt.y=y1;
		}
		else if(fabs(x4-x3)<mindouble)//直线水平
		{	joinpnt.x=x1;
			joinpnt.y=y2;
		}
		else 
		{
			double k1=(x3-x4)/(y4-y3);
			double k2=(y4-y3)/(x4-x3);										
			joinpnt.x=(double) ((y1-y2+k1*x2-k2*x1)/(k1-k2));
			joinpnt.y=(double) (k1*(joinpnt.x-x2)+y2);
		}	
	}
	aa=Distancef(joinpnt.x,joinpnt.y,x1,y1);	
	return aa;
}

//计算点到直线的垂直交点
//p1即直线外一点
//p2为直线上一点
//angle直线的斜率角
//函数返回计算得到的交点
CPnt PointToLineJoin(CPnt p1,CPnt p2,double angle)
{
	double x1,y1,x2,y2;
	x1=p1.x; y1=p1.y;	
	x2=p2.x; y2=p2.y;	
	CPnt joinpnt;//直线与过p1点的垂线的交点
	if(angle<0)	angle+=2*pi;
	if(angle>=2*pi) angle-=2*pi;
	//直线垂直
	if(fabs(angle-pi/2)<mindouble||fabs(angle-3*pi/2)<mindouble)
	{	joinpnt.x=x2;
		joinpnt.y=y1;
	}
	//直线水平
	else if(fabs(angle-pi)<mindouble||fabs(angle)<mindouble||fabs(angle-2*pi)<mindouble)
	{	joinpnt.x=x1;
		joinpnt.y=y2;
	}
	else 
	{
		double k1=tan(angle);
		double k2=-1/k1;							
		joinpnt.x=(double) ((y1-y2+k1*x2-k2*x1)/(k1-k2));
		joinpnt.y=(double) (k1*(joinpnt.x-x2)+y2);
	}	
	return joinpnt;
}


//计算点到直线的垂直距离
//p1即直线外一点
//p2为直线上一点
//angle直线的斜率角
//函数返回计算得到的距离值
double PointToLine11(CPnt p1,CPnt p2,double angle)
{
	double x1,y1,x2,y2,aa;
	x1=p1.x; y1=p1.y;	
	x2=p2.x; y2=p2.y;	
	CPnt joinpnt;//直线与过p1点的垂线的交点
	//直线垂直
	if(fabs(angle-pi/2)<mindouble||fabs(angle-3*pi/2)<mindouble)
	{	joinpnt.x=x2;
		joinpnt.y=y1;
	}
	//直线水平
	else if(fabs(angle-pi)<mindouble||fabs(angle)<mindouble||fabs(angle-2*pi)<mindouble)
	{	joinpnt.x=x1;
		joinpnt.y=y2;
	}
	else 
	{
		double k1=tan(angle);//(y4-y3)/(x4-x3);
		double k2=-1/k1;//(x3-x4)/(y4-y3);							
		joinpnt.x=(double) ((y1-y2+k1*x2-k2*x1)/(k1-k2));
		joinpnt.y=(double) (k1*(joinpnt.x-x2)+y2);
	}	
	aa=Distancef(joinpnt.x,joinpnt.y,x1,y1);	
	return aa;
}

//计算点到直线段的距离
//点(xx,yy)到直线段(x1,y1),(x2,y2)的距离
//函数返回计算得到的距离值
double PointToLine(double xx,double yy,double x1,double y1,double x2,double y2)
{
	double a,b,c,ang1,ang2,ang;
	//计算三条边的距离
	a=Distancef(x1,y1,xx,yy);
	if(a==0.0)	return 0.0;
	b=Distancef(x2,y2,xx,yy);
	if(b==0.0)	return 0.0;
	c=Distancef(x1,y1,x2,y2);
	if(c==0.0)//线段为一个点
		return a;
	if(a<b)//如果点到线段起点的这条边较短
	{
		if(y1==y2)
		{
			if(x1<x2)
				ang1=0;
			else
				ang1=(double)pi;
		}
		else
		{
			double yh=(x2-x1)/c;
			if(yh<-1) yh=-1;
			if(yh>1) yh=1;
			ang1=acos(yh);
			if(y1>y2) ang1=(double)pi*2-ang1;//直线(x1,y1)-(x2,y2)斜率的弧度
		}
		double yh=(xx-x1)/a;
		if(yh<-1) yh=-1;
		if(yh>1) yh=1;
		ang2=acos(yh);
		if(y1>yy) ang2=(double)pi*2-ang2;//直线(x1,y1)-(xx,yy)斜率的弧度
		ang=ang2-ang1;
		if(ang<0) ang=-ang;
		if(ang>pi) ang=(double)pi*2-ang;//交角大小
		if(ang>pi/2)	//若为钝角,直接得到距离为a
			return a;
		else				//锐角则计算得到距离
			return (a*(double)sin(ang));
		
	}
	else//如果点到线段终点的这条边较短
	{
		if(y1==y2)
		{
			if(x1<x2)
				ang1=(double)pi;
			else
				ang1=0;
		}
		else
		{
			double yh=(x1-x2)/c;
			if(yh<-1) yh=-1;
			if(yh>1) yh=1;
			ang1=acos(yh);
			if(y2>y1) ang1=(double)pi*2-ang1;//直线(x2,y2)-(x1,y1)斜率的弧度
		}
		double yh=(xx-x2)/b;
		if(yh<-1) yh=-1;
		if(yh>1) yh=1;
		ang2=acos(yh);
		if(y2>yy) ang2=(double)pi*2-ang2;//直线(x2,y2)-(xx,yy)斜率的弧度
		ang=ang2-ang1;
		if(ang<0) ang=-ang;
		if(ang>pi) ang=(double)pi*2-ang;
		if(ang>pi/2)	
			return b;	
		else
			return (b*(double)sin(ang));		
	}
}

//判断两角是否相等
BOOL AngleJudge(double angle1,double angle2)
{
	double Temp =fabs(angle1- angle2);
	return (Temp<mindouble||fabs(2*pi-Temp)<mindouble||fabs(pi-Temp)<mindouble);
}
/////////////////////////////////////////////////////////////////////////////
// CPaintobjApp initialization

BOOL CPaintobjApp::InitInstance()
{
	AfxEnableControlContainer();
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));

	LoadStdProfileSettings();  // Load standard INI file options (including MRU)

	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.

	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CPaintobjDoc),
		RUNTIME_CLASS(CMainFrame),          // standard MDI child frame
		RUNTIME_CLASS(CPaintobjView));
	AddDocTemplate(pDocTemplate);
/*	得到文档指针
	POSITION position = 
		pDocTemplate -> GetFirstDocPosition();
	m_pDocument =
		(CPaintobjDoc*) (pDocTemplate -> GetNextDoc(position));

	得到视图指针
	POSITION pos = m_pDocument->GetFirstViewPosition();
	if(pos != NULL)
	{
		CPaintobjView* m_pView =(CPaintobjView*) m_pDocument->GetNextView(pos);
	}   
*/
	// Enable DDE Execute open
	EnableShellOpen();
	RegisterShellFileTypes();
	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// The one and only window has been initialized, so show and update it.
	m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
	m_pMainWnd->UpdateWindow();

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

// Implementation
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//{{AFX_MSG(CAboutDlg)
	afx_msg void OnPaint();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CPaintobjApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}


void CAboutDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	//dc.MoveTo(-10,-10);
	//dc.LineTo(300,100);
	// Do not call CDialog::OnPaint() for painting messages
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -