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

📄 line.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(1)//鼠标移动画弧时,实时计算弧的各要素。
	{
		//m_TheFirst=0;
		Calculate(m_pointEnd);
		DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
		DPtoVP(m_plowerright,m_plowerright1);
		DPtoVP(m_pointPrimary,m_pointPrimary1);
		DPtoVP(m_pointEnd,m_pointEnd1);
		DPtoVP(m_pcirclecenter,m_pcirclecenter1);
		if(m_uArcPathDirection==0)
		{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointPrimary1.x,m_pointPrimary1.y,m_pointEnd1.x,m_pointEnd1.y);	
		}
		else
		{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointEnd1.x,m_pointEnd1.y,m_pointPrimary1.x,m_pointPrimary1.y);
		}
		pDC->MoveTo(m_pcirclecenter1.x,m_pcirclecenter1.y);
		pDC->LineTo(m_pointEnd1.x,m_pointEnd1.y);
	}
	if(1)//鼠标移动画弧时,实时计算弧的各要素。
	{		
		Calculate(pointDragged);
		DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
		DPtoVP(m_plowerright,m_plowerright1);
		DPtoVP(m_pointPrimary,m_pointPrimary1);
		DPtoVP(pointDragged,m_pointDragged);
		DPtoVP(m_pcirclecenter,m_pcirclecenter1);
		m_pointEnd.x=pointDragged.x;
		m_pointEnd.y=pointDragged.y;
		if(m_uArcPathDirection==0)
		{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointPrimary1.x,m_pointPrimary1.y,m_pointDragged.x,m_pointDragged.y);	
		}
		else
		{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointDragged.x,m_pointDragged.y,m_pointPrimary1.x,m_pointPrimary1.y);
		}
		pDC->MoveTo(m_pcirclecenter1.x,m_pcirclecenter1.y);
		pDC->LineTo(m_pointDragged.x,m_pointDragged.y);
	}
	pDC->SelectObject(pOldPen);
}

void CPaintArc::DrawSelected(CDC* pDC, void* pTemp)
{	
	pDC->SetROP2(R2_COPYPEN);
	COLORREF color=GetSysColor(COLOR_WINDOW);	
	CBrush 	DrawBrush;
	CBrush* pOldBrush;
//	pOldBrush = (CBrush *) pDC->SelectStockObject(HOLLOW_BRUSH);
	DrawBrush.CreateSolidBrush(color);
	pOldBrush = pDC->SelectObject(&DrawBrush);
	CPen*	pOldPen;
	CPen	pDrawPen;
	CPoint m_pupperleft1;
	CPoint m_plowerright1;
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(m_plowerright,m_plowerright1);
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);	
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	if(m_uArcPathDirection==0)
		pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointPrimary1.x,m_pointPrimary1.y,m_pointEnd1.x,m_pointEnd1.y);
	else
		pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointEnd1.x,m_pointEnd1.y,m_pointPrimary1.x,m_pointPrimary1.y);
	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 CPaintArc::DrawSpecialNode(CDC* pDC)//显示断点非相切点
{
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(WHITE_BRUSH);
	CPoint m_pupperleft1;
	CPoint m_plowerright1;
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(m_plowerright,m_plowerright1);
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(m_pointEnd,m_pointEnd1);	
	pDrawPen.CreatePen(PS_SOLID, m_nWidth, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	if(m_uArcPathDirection==0)
		pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointPrimary1.x,m_pointPrimary1.y,m_pointEnd1.x,m_pointEnd1.y);
	else
		pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pointEnd1.x,m_pointEnd1.y,m_pointPrimary1.x,m_pointPrimary1.y);

	//m_uStartNodeState;//起点状态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);
	}
	//m_uEndNodeState;//终点状态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->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);
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}
void CPaintArc::OnDown(CPnt& pointDown)
{
	m_pointEnd.x = m_pointPrimary.x = pointDown.x;
	m_pointEnd.y = m_pointPrimary.y = pointDown.y;
	m_pdiscirclecenter.x=pointDown.x;
	m_pdiscirclecenter.y=pointDown.y;
}
void CPaintArc::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;	
	m_pcirclecenter.x=m_pcirclecenter.x-pnt.x;
	m_pcirclecenter.y=m_pcirclecenter.y-pnt.y;
	m_pupperleft.x=m_pupperleft.x-pnt.x;
	m_pupperleft.y=m_pupperleft.y-pnt.y;
	m_plowerright.x=m_plowerright.x-pnt.x;
	m_plowerright.y=m_plowerright.y-pnt.y;

}
void CPaintArc::OnDown2(CPnt& pointDown)
{
	m_pcirclecenter.x=pointDown.x;
	m_pcirclecenter.y=pointDown.y;
}
void CPaintArc::OnUp(CPnt& pointUp, CWnd* pWnd)
{
	CClientDC tempDC(pWnd);
	Draw(&tempDC);
}
//
//判断是否点击了某节点
//返回0==没击中,1==击中起点,2==击中终点
UINT CPaintArc::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 CPaintArc::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 CPaintArc::IsHit(CPnt& pointBang)
{
	CPoint m_pointPrimary1;
	CPoint m_pointBang1;
	CPoint m_pcirclecenter1;
	DPtoVP(m_pointPrimary,m_pointPrimary1);
	DPtoVP(pointBang,m_pointBang1);
	DPtoVP(m_pcirclecenter,m_pcirclecenter1);
	double dDist=(double)sqrt((m_pointBang1.x - m_pcirclecenter1.x)*(m_pointBang1.x - m_pcirclecenter1.x)+(m_pointBang1.y - m_pcirclecenter1.y)*(m_pointBang1.y - m_pcirclecenter1.y))
		-(double)sqrt((m_pointPrimary1.x - m_pcirclecenter1.x)*(m_pointPrimary1.x - m_pcirclecenter1.x)+(m_pointPrimary1.y - m_pcirclecenter1.y)*(m_pointPrimary1.y - m_pcirclecenter1.y));
	if (fabs(dDist)<2)
	{	
		// Caculate the line's slant angle
		double fTemp = atan2(pointBang.y - m_pcirclecenter.y, pointBang.x - m_pcirclecenter.x);
		CAngle angSlant = CAngle(fTemp);
		CAngle angStart=CAngle(m_Angle1); //轨迹起始角
		CAngle angEnd=CAngle(m_Angle2);    //轨迹终止角		
		if( m_uArcPathDirection == 1 ) //顺时针轨迹
		{  		
			CAngle angTemp1=angSlant-angEnd;
			CAngle angTemp2=angStart-angEnd;    	 
			if(angTemp1.m_fRad <= angTemp2.m_fRad) //线段的倾角在轨迹的倾角范围内 
				return TRUE;			
			else
				return FALSE;
		}
		else //逆时针轨迹
		{   		
			CAngle angTemp1=angSlant-angStart;
			CAngle angTemp2=angEnd-angStart;    	 
			if(angTemp1.m_fRad <= angTemp2.m_fRad)  //线段的倾角在轨迹的倾角范围内  			
				return TRUE;			 	
			else
				return FALSE;
		}		
	}
	else
		return FALSE;		
}
//逆时针圆弧边界算法与顺时针圆弧边界算法有区别

void CPaintArc::GetBoundingRect(double &minx,double &miny,double &maxx,double &maxy)
{
	double x,y,x1,y1,x2,y2,an1,an2;
	int i,pb;
	//根据圆弧方向确定起终弧度
	if(m_uArcPathDirection==0)//逆时针圆弧
	{
		an1=m_Angle1;
		an2=m_Angle2;
	}
	else//顺时针圆弧
	{
		an1=m_Angle2;
		an2=m_Angle1;
	}
	//得到圆弧起点坐标m_pointPrimary
	x=m_pointPrimary.x;
	y=m_pointPrimary.y;
//	x=m_pcirclecenter.x+(double)(cos(m_Angle1)*m_nr);
//	y=m_pcirclecenter.y+(double)(sin(m_Angle1)*m_nr);
	x1=x;y1=y;x2=x;y2=y;//矩形边界初始化
	//得到圆弧终点坐标m_pointEnd
	x=m_pointEnd.x;
	y=m_pointEnd.y;
//	x=m_pcirclecenter.x+(double)(cos(m_Angle2)*m_nr);
//	y=m_pcirclecenter.y+(double)(sin(m_Angle2)*m_nr);
	//得到最小和最大坐标
	x1=min(x,x1);x2=max(x,x2);y1=min(y,y1);y2=max(y,y2);
	if(an1<an2) pb=1;//圆弧不经过x轴正向
	else						//与x轴正向相交
	{
		x=m_pcirclecenter.x+m_nr;y=m_pcirclecenter.y;//与x轴正向交点坐标
		//得到最小和最大坐标
		x1=min(x,x1);x2=max(x,x2);y1=min(y,y1);y2=max(y,y2);
		pb=2;					//表示跨过x轴正向
	}
	for(i=1;i<4;i++)//对另外三坐标轴循环
	{
		//如果坐标轴与弧相交
		if(pb==1 && pi/2*i>an1 && pi/2*i<an2 ||
		   pb==2 && !(pi/2*i>an2 && pi/2*i<an1))
		{
			if(i==1)//与y轴正向相交
			{
				x=m_pcirclecenter.x;y=m_pcirclecenter.y+m_nr;//交点坐标
			}
			if(i==2)//与x轴负向相交
			{
				x=m_pcirclecenter.x-m_nr;y=m_pcirclecenter.y;//交点坐标
			}
			if(i==3)//与y轴负向相交
			{
				x=m_pcirclecenter.x;y=m_pcirclecenter.y-m_nr;//交点坐标
			}
			//得到最小和最大坐标
			x1=min(x,x1);x2=max(x,x2);y1=min(y,y1);y2=max(y,y2);		
		}
	}
	minx= x1;
	miny= y1;
	maxx= x2;
	maxy= y2;

}

void CPaintArc::Serialize(CArchive& ar)
{	
	CPainted::Serialize(ar);
	if (ar.IsStoring())
	{		
		ar << m_pointEnd;
		ar << m_nr;
		ar << m_pupperleft;
		ar << m_plowerright;
		ar << m_pcirclecenter;
		ar << m_uArcPathDirection;
		ar <<m_Angle1;
		ar <<m_Angle2;
		ar <<m_nArcType;
	}
	else
	{		
		ar >> m_pointEnd;
		ar >> m_nr;
		ar >> m_pupperleft;
		ar >> m_plowerright;
		ar >> m_pcirclecenter;
		ar >> m_uArcPathDirection;
		ar >>m_Angle1;
		ar >>m_Angle2;
		ar >>m_nArcType;
	}
}

//通过改变圆弧属性来改变圆弧形状
//经考虑方案定为:
//起点不变,因为起点可能与某线段相连并相切,这正是所希望的
//圆心改变,并且圆心坐标一般情况下心算或手算可以得到
//终点改变,因为经常的情况是要使其与某线段相连并相切
//终点坐标一般情况下心算或手算可以得到
void CPaintArc::onup1(CPnt& point1, CPnt& point2, CPnt& point3,CWnd *pWnd)
{	//返回值定义:point1起点,point2圆心,point3终点
	m_pointPrimary=point1;//
	m_pcirclecenter=point2;

	if(Calculate1(point3))//计算弧的各要素
		{
		CClientDC tempDC(pWnd);
		Draw(&tempDC);
		}
}

CPnt CPaintArc::returnattr1()
{
	return m_pointPrimary;	
}
CPnt CPaintArc::returnattr2()
{
	return	m_pointEnd;
}

//返回路段给定端点的姿态角(外射角)
double CPaintArc::ReturnPostureAngle(UINT id)
{
	double angle;
	if(m_uStartNodeId==id)
		angle=m_StartPostureAngle;
	else
		angle=m_EndPostureAngle;
	return angle;
}

void CPaintArc::GetPostureAngle()//计算得到路段的姿态角(外射角)
{
	if(m_uArcPathDirection==0)//逆时针
	{			
		m_StartPostureAngle=m_Angle1-pi/2;
		if(m_StartPostureAngle<0) m_StartPostureAngle+=2*pi;
		m_EndPostureAngle=m_Angle2+pi/2;
		if(m_EndPostureAngle>=2*pi) m_EndPostureAngle-=2*pi;
	}
	else//顺时针
	{
		m_StartPostureAngle=m_Angle1+pi/2;
		if(m_StartPostureAngle>=2*pi) m_StartPostureAngle-=2*pi;
		m_EndPostureAngle=m_Angle2-pi/2;
		if(m_EndPostureAngle<0) m_EndPostureAngle+=2*pi;
	}
	
}

//给定两直线用圆弧连接
//半径定长
//更改两条直线的参考节点
void CPaintArc::JoinTwolines(CPaintobjDoc* pDoc)
{	
	CPainted*  pPainted1;
	CPainted*  pPainted2;
	if(pDoc->m_nGraphSelect==2)//给定两条直线
	{
		CPnt p11,p21;//直线L1,L2的参考点
		CPnt p12,p22;//直线L1,L2的另外一点
		CPnt JointPoint;//直线L1,L2的交点
		CPnt p0,p1,p2;//圆心及直线新的端点
		double k1,k2;//斜率
		double angle11,angle12;//直线L1两端点相对交点的角度
		double angle21,angle22;//直线L2两端点相对交点的角度
		double angle3,angle4;//两直线夹角及圆心所在直线的角度
		double r11,r12;//直线L1两端点相对交点的距离
		double r21,r22;//直线L2两端点相对交点的距离
		double rr;//圆心到交点的距离
		UINT id1,id2;//圆弧起点ID及终点ID

		pPainted1=pDoc->GetShape(pDoc->Graph

⌨️ 快捷键说明

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