📄 line.cpp
字号:
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 + -