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

📄 paintlazys.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PaintLazys.cpp: implementation of the CPaintLazys class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "const.h"
#include "paintobj.h"
#include "painted.h"
#include "paintdoc.h"
#include "math.h"
#include "SearchPath.h"
#include "SearchNode.h"
#include "paintvw.h"
#include "PaintLazys.h"
#include "LazysAttrDlg.h"
#include "BuildingLazysAttrDlg.h"
#include "DeviceLazysAttrDlg.h"
#include "LazysPath.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern double fscale;
extern void DPtoVPf(CPnt pnt,CPnt& point);
extern void DPtoVP(CPnt pnt,CPoint& point);
extern void VPtoDP(CPoint point,CPnt& pnt);
extern double Distance(int x1, int y1, int x2, int y2);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL(CPaintLazys, CObject, VERSIONABLE_SCHEMA)
CPaintLazys::CPaintLazys()
{

}

CPaintLazys::~CPaintLazys()
{

}

void CPaintLazys::Draw(CDC* pDC)
{	
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;
	
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);

	CPnt pntt,pntEnd;
	DPtoVPf(m_pointEnd,pntEnd);//把最终实际坐标变换为用于显示的逻辑坐标
	Transform1(pntEnd,pntt);
	double mm=pntt.x;
	double nn=pntt.y;
	CPnt pxy;
	CPnt pdraw;
	if(mm>0)
	{
		for(int jj=0;jj<=mm;jj++)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}
	else
	{
		for(int jj=0;jj>=mm;jj--)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}	

	pDC->SelectObject(pOldPen);
}

void CPaintLazys::DragDraw(CDC* pDC, CPnt& pointDragged)
{
	pDC->SetROP2(R2_NOT);//R2_XORPEN   R2_NOTMASKPEN 	
	CPen*	pOldPen;
	CPen	pDrawPen;	
	pDrawPen.CreatePen(PS_SOLID, int(fscale*m_nWidth)>2? 1:1, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);

	CPnt pntt,pntEnd;
	DPtoVPf(m_pointEnd,pntEnd);//把最终实际坐标变换为用于显示的逻辑坐标
	Transform1(pntEnd,pntt);
	double mm=pntt.x;
	double nn=pntt.y;
	CPnt pxy;
	CPnt pdraw;
	if(mm>0)
	{
		for(int jj=0;jj<=mm;jj++)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}
	else
	{
		for(int jj=0;jj>=mm;jj--)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}	
	///////////////////////////////////////////////////////////
	m_pointEnd.x=pointDragged.x;
	m_pointEnd.y=pointDragged.y;
	
	DPtoVPf(m_pointEnd,pntEnd);//把最终实际坐标变换为用于显示的逻辑坐标
	Transform1(pntEnd,pntt);
	mm=pntt.x;
	nn=pntt.y;	
	if(mm>0)
	{
		for(int jj=0;jj<=mm;jj++)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}
	else
	{
		for(int jj=0;jj>=mm;jj--)
		{
			pxy.x=double(jj);
			pxy.y=calculate(pxy.x,mm,nn);
			Transform(pxy,pdraw);//坐标变换
			if(jj==0)
			{
				pDC->MoveTo(int(pdraw.x),int(pdraw.y));
			}
			pDC->LineTo(int(pdraw.x),int(pdraw.y));		
		}
	}

	pDC->SelectObject(pOldPen);
}

//坐标变换
//从曲线的自身坐标系-》逻辑坐标系
//参数说明如下:
//m_pntStart:曲线在逻辑坐标系中起点坐标
//2*pi-m_angStart:起点的倾斜角(与逻辑坐标系X轴正向夹角)
//pnt:自身坐标系中某点的坐标
//point:某点经坐标变换后得到该点在逻辑坐标系中的坐标
void CPaintLazys::Transform(CPnt pnt,CPnt& point)
{
	CPnt m_pntStart;
	DPtoVPf(m_pointPrimary,m_pntStart);
	point.x=m_pntStart.x+pnt.x*cos(2*pi-m_angStart)-pnt.y*sin(2*pi-m_angStart);
	point.y=m_pntStart.y+pnt.x*sin(2*pi-m_angStart)+pnt.y*cos(2*pi-m_angStart);
}

//坐标变换
//从逻辑坐标系-》曲线的自身坐标系
void CPaintLazys::Transform1(CPnt pnt,CPnt& point)
{	
	CPnt m_pntStart;
	DPtoVPf(m_pointPrimary,m_pntStart);
	point.x=(pnt.x-m_pntStart.x)*cos(2*pi-m_angStart)+(pnt.y-m_pntStart.y)*sin(2*pi-m_angStart);
	point.y=(m_pntStart.x-pnt.x)*sin(2*pi-m_angStart)-(m_pntStart.y-pnt.y)*cos(2*pi-m_angStart);

}
//LAZY-S曲线方程
//参数定义:fX为实时的X轴坐标,返回值为实时的Y轴坐标
//m_fXe为曲线在X轴方向上的宽度(终点-起点)
//m_fYe为曲线在Y轴方向上的宽度(终点-起点),m_fYe为正时为标准形状
//m_fYe为负时为标准形状的镜相
double CPaintLazys::calculate(double fX,double m_fXe,double m_fYe)
{
	double fRate = fX / m_fXe;
	return m_fYe*fRate*fRate*fRate*(10-fRate*(15-6*fRate));
}
//LAZY-S曲线近似方程
//参数定义:x为实时的X轴坐标,y为实时的Y轴坐标
//mm为曲线在X轴方向上的宽度
//nn为曲线在Y轴方向上的宽度
//y=(sin(x*pi/mm-pi/2)*nn/2+nn/2);


void CPaintLazys::MoveDraw(CDC* pDC, CPnt& p1,CPnt& p2)
{
	pDC->SetROP2(R2_XORPEN);//R2_XORPEN	
	CPen*	pOldPen;
	CPen	pDrawPen;
	CPoint m_pp1;
	CPoint m_pp2;
	CPoint pp1;
	CPoint pp2;
	DPtoVP(m_p1,m_pp1);
	DPtoVP(m_p2,m_pp2);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(p1,pp1);
	DPtoVP(p2,pp2);
	pDrawPen.CreatePen(PS_DOT, 0, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	if(m_bFirstMove)//第一次移动
	{
		m_bFirstMove=FALSE;
		pDC->MoveTo(pp1.x,pp1.y);
		pDC->LineTo(pp2.x,pp2.y);
	}
	else
	{
		pDC->MoveTo(m_pp1.x,m_pp1.y);
		pDC->LineTo(m_pp2.x,m_pp2.y);
		pDC->MoveTo(pp1.x,pp1.y);
		pDC->LineTo(pp2.x,pp2.y);
	}
	m_p1=p1;
	m_p2=p2;
	pDC->SelectObject(pOldPen);
}

void CPaintLazys::DrawErase1(CDC* pDC, void* pTemp)//擦除图形WHITE_BRUSHHOLLOW_BRUSH
{	
	CPoint pointPrimary;
	CPoint pointEnd;
	CPoint p11,p12,p21,p22;
	DPtoVP(m_pointPrimary,pointPrimary);
	DPtoVP(m_pointEnd,pointEnd);//把最终实际坐标变换为用于显示的逻辑坐标
	p11.x=pointPrimary.x-4;
	p11.y=pointPrimary.y-4;
	p12.x=pointPrimary.x+4;
	p12.y=pointPrimary.y+4;
	p21.x=pointEnd.x-4;
	p21.y=pointEnd.y-4;
	p22.x=pointEnd.x+4;
	p22.y=pointEnd.y+4;	
	pDC->LPtoDP(&p11);
	pDC->LPtoDP(&p12);
	pDC->LPtoDP(&p21);
	pDC->LPtoDP(&p22);
	CRect rect1(p11.x,p11.y,p12.x,p12.y);
	CRect rect2(p21.x,p21.y,p22.x,p22.y);	
	((CPaintobjView*)pTemp)->InvalidateRect(&rect1);
	((CPaintobjView*)pTemp)->InvalidateRect(&rect2);
}
void CPaintLazys::DrawErase(CDC* pDC, void* pTemp)//擦除图形WHITE_BRUSHHOLLOW_BRUSH
{	
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(HOLLOW_BRUSH);
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, RGB(255,255,255));
	pOldPen = pDC->SelectObject(&pDrawPen);	
	pDC->Rectangle(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	pDC->Rectangle(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
	pDC->Ellipse(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	pDC->Ellipse(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);

	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}

void CPaintLazys::DrawSpecialNode(CDC* pDC)//显示断点非相切点
{
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(WHITE_BRUSH);
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);	
	Draw(pDC);
	//起点状态0=相切点1=非相切点2=断点
	if(m_uStartNodeState==2)//断点
	{
		pDC->MoveTo(m_pointPrimary1.x-3,m_pointPrimary1.y-3);
		pDC->LineTo(m_pointPrimary1.x+4,m_pointPrimary1.y+4);
		pDC->MoveTo(m_pointPrimary1.x-3,m_pointPrimary1.y+3);
		pDC->LineTo(m_pointPrimary1.x+4,m_pointPrimary1.y-4);
	}
	else if(m_uStartNodeState==1)//非相切点
	{
		pDC->Rectangle(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	}
	//终点状态0=相切点1=非相切点2=断点
	if(m_uEndNodeState==2)//断点
	{
		pDC->MoveTo(m_pointEnd1.x-3,m_pointEnd1.y-3);
		pDC->LineTo(m_pointEnd1.x+4,m_pointEnd1.y+4);
		pDC->MoveTo(m_pointEnd1.x-3,m_pointEnd1.y+3);
		pDC->LineTo(m_pointEnd1.x+4,m_pointEnd1.y-4);
	}
	else if(m_uEndNodeState==1)//非相切点
	{
		pDC->Rectangle(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
	}
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}

void CPaintLazys::DrawSelected(CDC* pDC, void* pTemp)
{	 
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(WHITE_BRUSH);
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	Draw(pDC);
	if(m_bSelectStartNode)//TRUE表示图形元素起点被选中
	{		
		m_bSelectStartNode=FALSE;		
		pDC->Ellipse(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	}
	else if(m_bSelectEndNode)//TRUE表示图形元素终点被选中
	{
		m_bSelectEndNode=FALSE;		
		pDC->Ellipse(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
	}
	else if(!m_bReferencePoint)//参考点FALSE表示终点为参考点
	{	
		DrawErase(pDC, (CPaintobjView*)pTemp);//擦除图形
		pDC->Rectangle(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
		pDC->Ellipse(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
	}
	else
	{
		DrawErase(pDC, (CPaintobjView*)pTemp);//擦除图形
		pDC->Rectangle(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
		pDC->Ellipse(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	}
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}
/*
void CPaintLazys::DrawSpecialNode(CDC* pDC)//显示断点非相切点
{
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(WHITE_BRUSH);
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);	
	pDC->MoveTo(m_pointPrimary1.x,m_pointPrimary1.y);
	pDC->LineTo(m_pointEnd1.x,m_pointEnd1.y);
	//起点状态0=相切点1=非相切点2=断点
	if(m_uStartNodeState==2)//断点
	{
		pDC->MoveTo(m_pointPrimary1.x-3,m_pointPrimary1.y-3);
		pDC->LineTo(m_pointPrimary1.x+4,m_pointPrimary1.y+4);
		pDC->MoveTo(m_pointPrimary1.x-3,m_pointPrimary1.y+3);
		pDC->LineTo(m_pointPrimary1.x+4,m_pointPrimary1.y-4);
	}
	else if(m_uStartNodeState==1)//非相切点
	{
		pDC->Rectangle(m_pointPrimary1.x-4,m_pointPrimary1.y-4,m_pointPrimary1.x+4,m_pointPrimary1.y+4);
	}
	//终点状态0=相切点1=非相切点2=断点
	if(m_uEndNodeState==2)//断点
	{
		pDC->MoveTo(m_pointEnd1.x-3,m_pointEnd1.y-3);
		pDC->LineTo(m_pointEnd1.x+4,m_pointEnd1.y+4);
		pDC->MoveTo(m_pointEnd1.x-3,m_pointEnd1.y+3);
		pDC->LineTo(m_pointEnd1.x+4,m_pointEnd1.y-4);
	}
	else if(m_uEndNodeState==1)//非相切点
	{
		pDC->Rectangle(m_pointEnd1.x-4,m_pointEnd1.y-4,m_pointEnd1.x+4,m_pointEnd1.y+4);
	}
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}
*/
void CPaintLazys::OnDown(CPnt& pointDown)
{
	m_pointEnd.x = m_pointPrimary.x = pointDown.x;
	m_pointEnd.y = m_pointPrimary.y = pointDown.y;
}
/*
void CPaintLazys::ChangeOrigin(CPnt pnt)//改变坐标原点
{	
	m_pointPrimary.x=m_pointPrimary.x-pnt.x;
	m_pointPrimary.y=m_pointPrimary.y-pnt.y;
	m_pointEnd.x=m_pointEnd.x-pnt.x;
	m_pointEnd.y=m_pointEnd.y-pnt.y;
}
*/
void CPaintLazys::OnDown2(CPnt& pointDown)
{

}
void CPaintLazys::OnUp(CPnt& pointUp, CWnd* pWnd)
{
	CClientDC tempDC(pWnd);
	Draw(&tempDC);
}

//
//判断是否点击了某节点
//返回0==没击中,1==击中起点,2==击中终点
UINT CPaintLazys::IsHit1(CPnt& pointBang)
{
	UINT forreturn=0;
	CPoint m_pointPrimary1;	
	CPoint m_pointEnd1;
	CPoint m_pointBang1;

	DPtoVP(m_pointPrimary,m_pointPrimary1);	
	DPtoVP(m_pointEnd,m_pointEnd1);
	DPtoVP(pointBang,m_pointBang1);
	if(Distance(m_pointBang1.x,m_pointBang1.y,m_pointPrimary1.x,m_pointPrimary1.y)<4)
	{
		forreturn=1;
	}
	else if(Distance(m_pointBang1.x,m_pointBang1.y,m_pointEnd1.x,m_pointEnd1.y)<4)
	{
		forreturn=2;
	}
	return forreturn;
}

void CPaintLazys::IsDblClk(void* pTemp1,void* pTemp2)//是否被双击选中
{
	if(m_uObjectType==0)//地图对象的类型0=路径1=建筑2=设备
		IsDblClkPath(pTemp1,pTemp2);	
	else if(m_uObjectType==1)
		IsDblClkBuilding(pTemp1,pTemp2);
	else if(m_uObjectType==2)
		IsDblClkDevice(pTemp1,pTemp2);
}

BOOL CPaintLazys::IsHit(CPnt& pointBang)
{
	CPnt pntEnd1,pntEnd;
	DPtoVPf(m_pointEnd,pntEnd);//把最终实际坐标变换为用于显示的逻辑坐标
	Transform1(pntEnd,pntEnd1);
	double mm=pntEnd1.x;
	double nn=pntEnd1.y;

	int x1,y1,x2,y2;	
	x1=int(min(0,pntEnd1.x));
	y1=int(min(0,pntEnd1.y));
	x2=int(max(0,pntEnd1.x));
	y2=int(max(0,pntEnd1.y));
	CRect rect(x1-3,y1-3,x2+3,y2+3); 	

	CPnt Bang1,Bang;
	DPtoVPf(pointBang,Bang);//把最终实际坐标变换为用于显示的逻辑坐标
	Transform1(Bang,Bang1);
	CPoint bbb;
	bbb.x=int(Bang1.x);

⌨️ 快捷键说明

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