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