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

📄 line.cpp

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

#include "stdafx.h"
#include "const.h"
#include "painted.h"
#include "paintdoc.h"
#include "line.h"
#include "Lineattr.h"
#include "math.h"
#include "SearchPath.h"
#include "SearchNode.h"
#include "paintvw.h"
#include "Arcattr.h"
#include "LinePath.h"
#include "ArcPath.h"
#include "BuildingLineAttrDlg.h"
#include "BuildingArcAttrDlg.h"
#include "DeviceLineAttrDlg.h"
#include "DeviceArcAttrDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

extern double fscale;
extern double fbasicscale;
extern int m_wscreen;//客户区宽度(逻辑坐标)
extern double fxmin;
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);
extern double Distancef(double x1, double y1, double x2, double y2);
extern double PointToLine1(CPnt p1,CPnt p2,CPnt p3,CPnt p4,BOOL bbb);
extern double PointToLine11(CPnt p1,CPnt p2,double angle);
extern BOOL AngleJudge(double angle1,double angle2);
extern CPnt PointToLineJoin(CPnt p1,CPnt p2,double angle);
/////////////////////////////////////////////////////////////////////////////
// CPaintLine

//IMPLEMENT_SERIAL(CPaintLine, CPainted, VERSIONABLE_SCHEMA)
IMPLEMENT_SERIAL(CPaintLine, CObject, 1234)
CPaintLine::CPaintLine()
{
	m_bpointEndControl=0;//终点坐标控制	
	m_flength=0;//直线长度
	m_fangle=0;//直线角度
}
//用CPath数据初始化CPaintLine数据
void CPaintLine::Init(CPath* pPath)
{
	CLinePath* pLinePath=((CLinePath*) pPath);
	USHORT StartNodeId=pLinePath->m_uStartNode;//起点ID
	USHORT EndNodeId=pLinePath->m_uEndNode;//终点ID
	CNode* pStartNode=m_pDoc->GetNode(StartNodeId);
	CNode* pEndNode=m_pDoc->GetNode(EndNodeId);

	
	m_pointPrimary=CPnt(pStartNode->x,pStartNode->y);//起点坐标	
	m_uStartNodeId=StartNodeId;//起点ID
	m_uStartNodeType=pStartNode->m_uType;//起点类型
	m_uStartNodeExtType=pStartNode->m_uExtType;//起点扩展类型
	m_fStartHeading=pStartNode->m_fHeading;//起点车头方向角(度)

	m_pointEnd=CPnt(pEndNode->x,pEndNode->y);//终点坐标
	m_uEndNodeId=EndNodeId;//终点ID
	m_uEndNodeType=pEndNode->m_uType;//终点类型
	m_uEndNodeExtType=pEndNode->m_uExtType;//终点扩展类型
	m_fEndHeading=pEndNode->m_fHeading;//终点车头方向角(度)

	m_uFigureType=0;		//路径类型
	m_uPathId=pLinePath->m_uId;		//路径ID
	m_fPathLimit=pLinePath->m_fVeloLimit;	//速度限制
	m_uPathGuideType=pLinePath->m_uGuideType;	//导航方式
	m_uPathExtType=pLinePath->m_uExtType;	//路径扩展类型		
	m_uPathObstacle=pLinePath->m_uObstacle;//路径障碍物模式
	m_uPathHeading=pLinePath->m_uHeading;//路径车头方向	
	m_uObjectType=0;//地图对象的类型0=路径1=建筑2=设备		
	
	GetPostureAngle();//计算得到路段的姿态角(外射角)	
	//得到直线长度直线角度
	Calculate(m_pointEnd);	
}

void CPaintLine::Draw(CDC* pDC)
{	//pDC->SetROP2(R2_NOT);
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;

	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;

	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	//pDrawPen.CreatePen(PS_DOT, int(fscale*m_nWidth)>2? 1:1, m_rgbPrimary);
	pDrawPen.CreatePen(PS_SOLID, int(fscale*m_nWidth)>2? 1:1, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);

	pDC->MoveTo(m_pointPrimary1.x,m_pointPrimary1.y);
	pDC->LineTo(m_pointEnd1.x,m_pointEnd1.y);

	pDC->SelectObject(pOldPen);
}
void CPaintLine::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 CPaintLine::DragDraw(CDC* pDC, CPnt& pointDragged)
{
	pDC->SetROP2(R2_NOT);//R2_XORPEN   R2_NOTMASKPEN 	
	CPen*	pOldPen;
	CPen	pDrawPen;
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	CPoint m_pointDragged;

	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(pointDragged,m_pointDragged);

	pDrawPen.CreatePen(PS_DOT, 0, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);

	pDC->MoveTo(m_pointPrimary1.x,m_pointPrimary1.y);
	pDC->LineTo(m_pointEnd1.x,m_pointEnd1.y);
	
	pDC->MoveTo(m_pointPrimary1.x,m_pointPrimary1.y);
	pDC->LineTo(m_pointDragged.x,m_pointDragged.y);
	//得到直线长度直线角度
	Calculate(pointDragged);	
	m_pointEnd = pointDragged;
	pDC->SelectObject(pOldPen);
}

void CPaintLine::DrawSelected(CDC* pDC, void* pTemp)
{	 
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;	
	CBrush	DrawBrush;	

	DrawBrush.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
	pOldBrush = pDC->SelectObject(&DrawBrush);
//	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, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	pDC->MoveTo(m_pointPrimary1.x,m_pointPrimary1.y);
	pDC->LineTo(m_pointEnd1.x,m_pointEnd1.y);	
	if(m_bSelectStartNode)//TRUE表示图形元素起点被选中
	{	
	//	DrawErase(pDC, (CPaintobjView*)pTemp);//擦除图形
		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表示图形元素终点被选中
	{
	//	DrawErase(pDC, (CPaintobjView*)pTemp);//擦除图形
		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 CPaintLine::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 CPaintLine::OnDown(CPnt& pointDown)
{
	m_pointEnd.x = m_pointPrimary.x = pointDown.x;
	m_pointEnd.y = m_pointPrimary.y = pointDown.y;
}
void CPaintLine::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 CPaintLine::OnDown2(CPnt& pointDown)
{

}
void CPaintLine::OnUp(CPnt& pointUp, CWnd* pWnd)
{
	CClientDC tempDC(pWnd);
	Draw(&tempDC);
}
//
//判断是否点击了某节点
//返回0==没击中,1==击中起点,2==击中终点
UINT CPaintLine::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 CPaintLine::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 CPaintLine::IsHit(CPnt& pointBang)
{
	CPoint m_pointPrimary1;	
	CPoint m_pointEnd1;
	CPoint m_pointBang1;

	DPtoVP(m_pointPrimary,m_pointPrimary1);	
	DPtoVP(m_pointEnd,m_pointEnd1);
	DPtoVP(pointBang,m_pointBang1);

	double a,b,c,ang1,ang2,ang;
	double x1=(double) m_pointPrimary1.x;
	double y1=(double) m_pointPrimary1.y;
	double x2=(double) m_pointEnd1.x;
	double y2=(double) m_pointEnd1.y;
	double xx=(double) m_pointBang1.x;
	double yy=(double) m_pointBang1.y;
	//计算三条边的距离
	a=Distance1(x1,y1,xx,yy);
	if(a==0.0)	return TRUE;
	b=Distance1(x2,y2,xx,yy);
	if(b==0.0)	return TRUE;
	c=Distance1(x1,y1,x2,y2);
	if(c==0.0)//线段为一个点
	{
		if(a<3)
			return TRUE;
		else 
			return FALSE;
	}
	if(a<b)//如果点击的点到线段起点的这条边较短
	{
		if(y1==y2)
		{
			if(x1<x2)
				ang1=0;
			else
				ang1=(double)pi;
		}
		else
		{
			double x=(x2-x1)/c;
			if(x<-1) x=-1;
			if(x>1) x=1;
			ang1=acos(x);
			if(y1>y2) ang1=(double)pi*2-ang1;//直线(x1,y1)-(x2,y2)斜率的弧度
		}
		double x=(xx-x1)/a;
		if(x<-1) x=-1;
		if(x>1) x=1;
		ang2=acos(x);
		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
		{
			if(a<3)
				return TRUE;
			else 
				return FALSE;
		}
		else				//锐角则计算得到距离
		{
			if((a*(double)sin(ang))<3)
				return TRUE;
			else 
				return FALSE;
		}
	}
	else
	{
		if(y1==y2)
		{
			if(x1<x2)
				ang1=(double)pi;
			else
				ang1=0;
		}
		else
		{
			double x=(x1-x2)/c;
			if(x<-1) x=-1;
			if(x>1) x=1;
			ang1=acos(x);
			if(y2>y1) ang1=(double)pi*2-ang1;//直线(x2,y2)-(x1,y1)斜率的弧度
		}
		double x=(xx-x2)/b;
		if(x<-1) x=-1;
		if(x>1) x=1;
		ang2=acos(x);
		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)	
		{
			if(b<3)
				return TRUE;
			else 
				return FALSE;
		}
		else
		{
			if((b*(double)sin(ang))<3)
				return TRUE;
			else 
				return FALSE;
		}
	}
}

void CPaintLine::GetBoundingRect(double &minx,double &miny,double &maxx,double &maxy)

⌨️ 快捷键说明

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