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

📄 line.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						forreturn=TRUE;
					}
					break;
				}
			}
		}//
	 }
	 return forreturn;
}
IMPLEMENT_SERIAL(CPaintArc, CObject, VERSIONABLE_SCHEMA)

CPaintArc::CPaintArc()
{	m_pupperleft= CPnt(0,0);
	m_plowerright = CPnt(0,0);	
	m_pointEnd= CPnt(0,0);
	m_uArcPathDirection=0;
    m_ncirclecenterControl=0;//圆心坐标控制
	m_TheFirst=TRUE;
}

//用CPath数据初始化CPaintArc数据
void CPaintArc::Init(CPath* pPath)
{
	CArcPath* pArcPath=((CArcPath*) pPath);
	USHORT StartNodeId=pArcPath->m_uStartNode;//起点ID
	USHORT EndNodeId=pArcPath->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=1;		//路径类型
	m_uPathId=pArcPath->m_uId;		//路径ID
	m_fPathLimit=pArcPath->m_fVeloLimit;	//速度限制
	m_uPathGuideType=pArcPath->m_uGuideType;	//导航方式
	m_uPathExtType=pArcPath->m_uExtType;	//路径扩展类型		
	m_uPathObstacle=pArcPath->m_uObstacle;//路径障碍物模式
	m_uPathHeading=pArcPath->m_uHeading;//路径车头方向		
	m_pcirclecenter=CPnt(pArcPath->m_fCenterx,pArcPath->m_fCentery);	//圆心坐标
	m_uArcPathDirection=pArcPath->m_uDirection;//圆弧方向0==anticlockwise
	
	Calculate(m_pointEnd);	
	m_nArcType=pArcPath->m_uType;//圆弧类型1--spp 2--spline 6--ARC
	m_uObjectType=0;//地图对象的类型0=路径1=建筑2=设备
	
	GetPostureAngle();//计算得到路段的姿态角(外射角)
	
}

//改变圆弧各元素后进行重新计算
BOOL CPaintArc::Calculate1(CPnt& point)
{
	double x1,y1,xx,yy,x2,y2;
	double rr,Angle2,m_nrr,Angle1;
	xx=m_pcirclecenter.x;
	yy=m_pcirclecenter.y;
	x1=m_pointPrimary.x;
	y1=m_pointPrimary.y;
	x2=point.x;
	y2=point.y;
	m_nr=(double)sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
	m_nrr=sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
	rr=sqrt((xx-x2)*(xx-x2)+(yy-y2)*(yy-y2));
	//得到终点相对圆心的弧度
	double x=(x2-xx)/rr;
	if(x<-1) x=-1;
	if(x>1) x=1;
	Angle2=acos(x);
	if(y2-yy<0)	Angle2=(pi*2-Angle2);
	m_Angle2=(double)Angle2;
	//得到终点坐标
	m_pointEnd.x=(double) (xx+m_nrr*cos(Angle2));
	m_pointEnd.y=(double) (yy+m_nrr*sin(Angle2));	
	//把计算得到的数据,存入类的各个变量中
	m_pupperleft.x=(double) (xx-m_nrr);
	m_pupperleft.y=(double) (yy+m_nrr);
	m_plowerright.x=(double) (xx+m_nrr);
	m_plowerright.y=(double) (yy-m_nrr);
	//得到起点相对圆心的弧度
	double yh=(x1-xx)/m_nrr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	Angle1=acos(yh);
	if(y1-yy<0)	Angle1=(pi*2-Angle1);
	m_Angle1=(double)Angle1;
	return TRUE;
}
//起点圆心法画弧计算方法如下:
//此函数经考虑,使传递来的CPnt& point为
//由CPaintobjView::GetArcEndnode(CPnt& pnt1)计算出的确切终点
//函数算法不变
BOOL CPaintArc::Calculate(CPnt& point)
{	
	double x1,y1,xx,yy,x2,y2;
	double Angle2,m_nrr,Angle1;
	xx=m_pcirclecenter.x;
	yy=m_pcirclecenter.y;
	x1=m_pointPrimary.x;
	y1=m_pointPrimary.y;
	x2=point.x;
	y2=point.y;
//	if(x1==x2&&y1==y2)
//	return FALSE;
	m_nr=sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
	m_nrr=sqrt((xx-x2)*(xx-x2)+(yy-y2)*(yy-y2));
	//得到点相对圆心的弧度
	double yh=(x2-xx)/m_nrr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	Angle2=acos(yh);
	if(y2-yy<0)	Angle2=(pi*2-Angle2);
	m_Angle2=Angle2;
	//把计算得到的数据,存入类的各个变量中
	m_pupperleft.x=(double) (xx-m_nr);
	m_pupperleft.y=(double) (yy+m_nr);
	m_plowerright.x=(double) (xx+m_nr);
	m_plowerright.y=(double) (yy-m_nr);
	//得到起点相对圆心的弧度
	yh=(x1-xx)/m_nr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	Angle1=acos(yh);
	if(y1-yy<0)	Angle1=(pi*2-Angle1);
	m_Angle1=Angle1;
	GetArcType();
	return TRUE;
}
/*
//三点法画弧计算方法如下
BOOL CPaintArc::Calculate(CPnt& point)
{	m_pointEnd.x = point.x;
	m_pointEnd.y = point.y;
	double x1,y1,x2,y2,x3,y3,xx1,xx2,yy1,yy2,xx,yy,rr;
	double k1,k2,an1,an2,an3;
	x1=m_pointPrimary.x;//将三点坐标赋给浮点变量
	y1=m_pointPrimary.y;
	x2=m_pointsecond.x;
	y2=m_pointsecond.y;
	x3=point.x;
	y3=point.y;
	if(x1==x2&&y1==y2||x1==x3&&y1==y3||x2==x3&&y2==y3)
		return FALSE;//如果有两个点相同,则操作不成功,返回0;
	xx1=(x1+x2)/2;yy1=(y1+y2)/2;//得到顺三点方向的两条
	xx2=(x2+x3)/2;yy2=(y2+y3)/2;//直线中点的坐标
	if(fabs(y2-y1)>0.0005)//如果第一条直线的垂线不是垂直线
		k1=-(x2-x1)/(y2-y1);//得到该直线的垂线的斜率
	
	if(fabs(y3-y2)>0.0005)//如果第二条直线的垂线不是垂直线
		k2=-(x3-x2)/(y3-y2);//得到该直线的垂线的斜率

	if(k1==k2&&k1==0.0)
		return FALSE;

	if(fabs(y2-y1)<0.0005)//如果第一条直线的垂线是垂直线
	{
		xx=xx1;//圆心坐标
		if(fabs(y3-y2)<0.0005)//如果第二条直线的垂线也是垂直线
		{
			yy=y2+10000;
			rr=10000;//假设圆弧半径为10000;
		}
		else //如果第二条直线的垂线不是垂直线
		{
			yy=yy2+k2*(xx2-xx);//圆心坐标
			rr=yy-y2;
			if(rr<0) rr=-rr;//	圆弧半径	
		}
	}
	else if(fabs(y3-y2)<0.0005)//如果第二条直线的垂线是垂直线,第一条不是
		{	xx=xx2;//圆心坐标
			yy=yy1+k1*(xx1-xx);
			rr=yy-y2;
			if(rr<0) rr=-rr;//	圆弧半径
		}
	else    //如果二条直线的垂线都不是垂直线
	{
		if(k1==k2)//如果二条直线平行,即三点一线
		{
			xx=x2+(double)(10000/sqrt(1+k1*k1));
			yy=y2+(double)(10000/sqrt((1+k1*k1)/(k1*k1)));
			rr=10000;
		}
		else//如果二条直线不平行
		{
			xx=(yy2-yy1+k1*xx1-k2*xx2)/(k1-k2);
			yy=yy1+k1*(xx-xx1);
			rr=(double)sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
		}
	}
//把计算得到的数据,存入类的各个变量中。
	m_pupperleft.x=xx-rr;
	m_pupperleft.y=yy-rr;
	
	m_plowerright.x=xx+rr;
	m_plowerright.y=yy+rr;
	m_nr=rr;
	m_pcirclecenter.x=xx;
	m_pcirclecenter.y=yy;
	//得到第一点相对圆心的弧度
	double yh=(x1-xx)/rr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	an1=acos(yh);
	if(y1-yy<0)	an1=(double)(pi*2-an1);
	//得到第二点相对圆心的弧度
	yh=(x2-xx)/rr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	an2=acos(yh);
	if(y2-yy<0)	an2=(double)(pi*2-an2);
	//得到第三点相对圆心的弧度
	yh=(x3-xx)/rr;
	if(yh<-1) yh=-1;
	if(yh>1) yh=1;
	an3=acos(yh);
	if(y3-yy<0)	an3=(double)(pi*2-an3);
	if(an2>an1&&an2<an1+pi || an2<an1&&an2+pi<an1)//若弧为逆时针方向
	{
		m_Angle1=an1;m_Angle2=an3;
	}
	else//若弧为顺时针方向
	{
		m_Angle1=an3;m_Angle2=an1;
	}
	
return TRUE;
}
*/
void CPaintArc::Draw(CDC* pDC)
{	
	pDC->SetROP2(R2_COPYPEN);
	CPen*	pOldPen;
	CPen	pDrawPen;

	pDrawPen.CreatePen(PS_SOLID, int(fscale*m_nWidth)>2? 1:1, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&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);
	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->SelectObject(pOldPen);
}
void CPaintArc::MoveDraw(CDC* pDC, CPnt& p1,CPnt& p2)
{
	pDC->SetROP2(R2_XORPEN);//R2_XORPEN	R2_NOT
	CPen*	pOldPen;
	CPen	pDrawPen;
	CPoint m_pupperleft1;
	CPoint m_plowerright1;
	CPoint m_pp1;
	CPoint m_pp2;
	CPoint pp1;
	CPoint pp2;	
	CPoint m_pcirclecenter1;//PS_DOT, 0, m_rgbPrimary
	pDrawPen.CreatePen(PS_DOT,0, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);
	if(m_bFirstMove)//第一次移动
	{
		m_bFirstMove=FALSE;
		if(1)//鼠标移动画弧时,实时计算弧的各要素。
		{
			Calculate(p2);
			DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
			DPtoVP(m_plowerright,m_plowerright1);
			DPtoVP(p1,pp1);
			DPtoVP(p2,pp2);
			DPtoVP(m_pcirclecenter,m_pcirclecenter1);		
			if(m_uArcPathDirection==0)
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,pp1.x,pp1.y,pp2.x,pp2.y);	
			}
			else
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,pp2.x,pp2.y,pp1.x,pp1.y);
			}		
			m_p1=p1;
			m_p2=p2;
			m_pupperleft2=m_pupperleft;
			m_plowerright2=m_plowerright;
			m_pcirclecenter2=m_pcirclecenter;
		}
	}
	else
	{	
		if(1)//鼠标移动画弧时,实时计算弧的各要素。
		{
			Calculate(m_p2);
			//把最终实际坐标变换为用于显示的逻辑坐标		
			DPtoVP(m_pupperleft2,m_pupperleft1);
			DPtoVP(m_plowerright2,m_plowerright1);
			DPtoVP(m_p1,m_pp1);
			DPtoVP(m_p2,m_pp2);		
			DPtoVP(m_pcirclecenter2,m_pcirclecenter1);
			if(m_uArcPathDirection==0)
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pp1.x,m_pp1.y,m_pp2.x,m_pp2.y);	
			}
			else
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,m_pp2.x,m_pp2.y,m_pp1.x,m_pp1.y);
			}		
		}
		if(1)//鼠标移动画弧时,实时计算弧的各要素。
		{
			Calculate(p2);
			DPtoVP(m_pupperleft,m_pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
			DPtoVP(m_plowerright,m_plowerright1);
			DPtoVP(p1,pp1);
			DPtoVP(p2,pp2);
			DPtoVP(m_pcirclecenter,m_pcirclecenter1);		
			if(m_uArcPathDirection==0)
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,pp1.x,pp1.y,pp2.x,pp2.y);	
			}
			else
			{	pDC->Arc(m_pupperleft1.x,m_pupperleft1.y,m_plowerright1.x,m_plowerright1.y,pp2.x,pp2.y,pp1.x,pp1.y);
			}		
			m_p1=p1;
			m_p2=p2;
			m_pupperleft2=m_pupperleft;
			m_plowerright2=m_plowerright;
			m_pcirclecenter2=m_pcirclecenter;
		}
	}
	pDC->SelectObject(pOldPen);
}
//动态显示半径和圆弧所在的圆
void CPaintArc::DragDrawCircle(CDC* pDC, CPnt& pnt,CPaintobjDoc* pDoc)
{
	pDC->SetROP2(R2_NOTXORPEN);//R2_NOTXORPEN   R2_NOT	
	double xx,yy,x1,y1;
	double rr;
	CPen*	pOldPen;
	CPen	pDrawPen;
	CBrush*	pOldBrush;		
	pOldBrush = (CBrush *) pDC->SelectStockObject(HOLLOW_BRUSH);
	CPnt startnode;
	CPnt discirclecenter;
	CPnt pupperleft;//左上角
	CPnt plowerright;//右下角
	CPoint startnode1;	
	CPoint	discirclecenter1;	
	CPoint pupperleft1;//左上角
	CPoint plowerright1;//右下角
	CPoint pnt1;
	CPoint pointPrimary1;
	DPtoVP(m_pointPrimary,pointPrimary1);

	discirclecenter=((CPaintArc*) pDoc->m_pSelectedTool)->m_pdiscirclecenter;
	startnode=((CPaintArc*) pDoc->m_pSelectedTool)->m_pointPrimary;
	DPtoVP(startnode,startnode1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(discirclecenter,discirclecenter1);
	DPtoVP(pnt,pnt1);	
	pDrawPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
	pOldPen = pDC->SelectObject(&pDrawPen);
	pDC->MoveTo(startnode1.x,startnode1.y);
	pDC->LineTo(discirclecenter1.x,discirclecenter1.y);
	xx=discirclecenter.x;
	yy=discirclecenter.y;
	x1=startnode.x;
	y1=startnode.y;		
	rr=sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
	pupperleft.x=xx-rr;
	pupperleft.y= yy+rr;
	plowerright.x=xx+rr;
	plowerright.y=yy-rr;
	DPtoVP(pupperleft,pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(plowerright,plowerright1);
//	pDC->Ellipse(pupperleft1.x,pupperleft1.y,plowerright1.x,plowerright1.y);
	pDC->Arc(pupperleft1.x,pupperleft1.y,plowerright1.x,plowerright1.y,pointPrimary1.x,pointPrimary1.y,pointPrimary1.x,pointPrimary1.y);	
	pDC->MoveTo(startnode1.x,startnode1.y);
	pDC->LineTo(pnt1.x,pnt1.y);
	xx=pnt.x;
	yy=pnt.y;
	x1=startnode.x;
	y1=startnode.y;		
	rr=sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1));
	pupperleft.x=xx-rr;
	pupperleft.y= yy+rr;
	plowerright.x=xx+rr;
	plowerright.y=yy-rr;
	DPtoVP(pupperleft,pupperleft1);//把最终实际坐标变换为用于显示的逻辑坐标
	DPtoVP(plowerright,plowerright1);
//	pDC->Ellipse(pupperleft1.x,pupperleft1.y,plowerright1.x,plowerright1.y);
	pDC->Arc(pupperleft1.x,pupperleft1.y,plowerright1.x,plowerright1.y,pointPrimary1.x,pointPrimary1.y,pointPrimary1.x,pointPrimary1.y);
	((CPaintArc*) pDoc->m_pSelectedTool)->m_pdiscirclecenter= pnt;
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldBrush);
}
void CPaintArc::DragDraw(CDC* pDC, CPnt& pointDragged)
{
	pDC->SetROP2(R2_NOT);//R2_XORPEN	R2_NOT
	CPen*	pOldPen;
	CPen	pDrawPen;
	CPoint m_pupperleft1;
	CPoint m_plowerright1;
	CPoint m_pointPrimary1;
	CPoint m_pointEnd1;
	CPoint m_pointDragged;
	CPoint m_pcirclecenter1;
	pDrawPen.CreatePen(PS_SOLID, int(fscale*m_nWidth)>2? 1:1, m_rgbPrimary);
	pOldPen = pDC->SelectObject(&pDrawPen);

⌨️ 快捷键说明

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