📄 paintobj.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 + -