📄 paintscp.cpp
字号:
CPainted* pPainted;
//若有一条参考线段并定义了参考点为其起点或终点
if(m_pDoc->m_nGraphSelect==1 && m_pDoc->GraphSelect[0].Type>=0 && m_pDoc->GraphSelect[0].Type<=4)
{
pPainted =m_pDoc->GetShape(m_pDoc->GraphSelect[0].Index);
if(!pPainted->m_bReferencePoint)//参考点为终点
{
CPnt ppp;
ppp=pPainted->returnattr2();
pnt=ppp;
angle=pPainted->m_EndPostureAngle;
id=pPainted->m_uEndNodeId;
forreturn=TRUE;
}
else//参考点为起点
{
CPnt ppp;
ppp=pPainted->returnattr1();
pnt=ppp;
angle=pPainted->m_StartPostureAngle;
id=pPainted->m_uStartNodeId;
forreturn=TRUE;
}
}
else//若没有一条参考线段
{
int nShapes = m_pDoc->NumShapes();
for (int index = 0; index < nShapes; index++)
{
pPainted =(CPainted*) m_pDoc->GetShape(index);
forreturn=pPainted->NearJudge2(pnt1,id,pnt,angle);
if(forreturn)
break;
}
}
return forreturn;
}
//得到路径的绘制起点
int CPaintScp::GetPathStartnode(CPnt& pnt1, CPnt& pnt2)
{
return 1;
}
//得到路径的绘制终点
BOOL CPaintScp::GetPathEndnode(CPnt& pnt1)
{
return 1;
}
//得到路径的绘制终点
//返回值==FALSE时表示终点独立(不与任何节点相连)
//返回值==TRUE时表示终点与某节点相连
//
BOOL CPaintScp::GetPathEndnode1(CPnt& pnt1)
{
BOOL forreturn=FALSE;
CPainted* pPainted;
if(m_pDoc->m_ScpPaintMode==2)
{
pnt1=m_pDoc->m_pPaintEndNode;//绘图时给定的终点
}
int nShapes = m_pDoc->NumShapes();
for (int index = 0; index < nShapes; index++)
{
UINT id;
CPnt pnt;
double angle;
pPainted =(CPainted*) m_pDoc->GetShape(index);
forreturn=pPainted->NearJudge2(pnt1,id,pnt,angle);
if(forreturn)
{
pnt1=pnt;
m_pDoc->m_uCurEndnodeId=id;
break;
}
}
return forreturn;
}
void CPaintScp::GetBoundingRect(double &minx,double &miny,double &maxx,double &maxy)
{
double xmin,xmax,ymin,ymax;
xmin=min(m_pointPrimary.x,m_pointEnd.x);
xmax=max(m_pointPrimary.x,m_pointEnd.x);
ymin=min(m_pointPrimary.y,m_pointEnd.y);
ymax=max(m_pointPrimary.y,m_pointEnd.y);
minx=xmin;
miny = ymin;
maxx =xmax;
maxy =ymax;
}
void CPaintScp::IsDblClk(void* pTemp1,void* pTemp2)//是否被双击选中
{
loop11:
m_pDoc = (CPaintobjDoc*) pTemp1;
CScpAttrDlg scpattr;
scpattr.m_pDoc =(CPaintobjDoc*) pTemp1;
scpattr.m_pActive1=this;
scpattr.m_dAngle=m_angStart*180.0/pi;
scpattr.m_uEndId =m_uEndNodeId;
scpattr.m_nHead =m_uPathHeading;
scpattr.m_uId = m_uPathId;
UINT id=m_uPathId;
scpattr.m_dLimit = m_fPathLimit;
scpattr.m_uStartId =m_uStartNodeId;
scpattr.m_nGuide=m_uPathGuideType;
int result=scpattr.DoModal();
if(result==IDOK)
{
//如果更改了路径编号,不能与某存在的路径编号相同
//必须定义新的路径编号
CPainted* pPainter;
if(id!=scpattr.m_uId)
{
BOOL breturn=FALSE;
int nShapes = m_pDoc->NumShapes();
for (int index = 0; index < nShapes; index++)
{
pPainter =m_pDoc->GetShape(index);
if(pPainter->m_uPathId==scpattr.m_uId)
{
CString str="更改后的路径编号不能与某存在的路径编号相同,必须重新定义新的路径编号!";
AfxMessageBox(str);
breturn=TRUE;
break;
}
}
if(breturn) {goto loop11;}
}
m_uPathHeading=scpattr.m_nHead;
m_uPathId=scpattr.m_uId;
m_fPathLimit=scpattr.m_dLimit;
m_uPathGuideType=scpattr.m_nGuide;
m_pDoc->GetPathIdMax();
}
}
//
//判断是否点击了某节点
//返回0==没击中,1==击中起点,2==击中终点
UINT CPaintScp::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;
}
BOOL CPaintScp::IsHit(CPnt& pointBang)
{
CPnt pntEnd1,pntEnd;
DPtoVPf(m_pointEnd,pntEnd);//把最终实际坐标变换为用于显示的逻辑坐标
Transform1(pntEnd,pntEnd1);
double mm=pntEnd1.x;
double nn=pntEnd1.y;
int x1,y1,x2,y2;
x1=int(min(0,pntEnd1.x));
y1=int(min(0,pntEnd1.y));
x2=int(max(0,pntEnd1.x));
y2=int(max(0,pntEnd1.y));
CRect rect(x1-3,y1-3,x2+3,y2+3);
CPnt Bang1,Bang;
DPtoVPf(pointBang,Bang);//把最终实际坐标变换为用于显示的逻辑坐标
Transform1(Bang,Bang1);
CPoint bbb;
bbb.x=int(Bang1.x);
bbb.y=int(Bang1.y);
if (!rect.PtInRect(bbb))
return FALSE;
else
{
//进一步判断点是否在曲线上
double yyyy=calculate(Bang1.x,mm,nn);
if(fabs(yyyy-Bang1.y)<5)
return TRUE;
else
return FALSE;
}
}
void CPaintScp::Serialize(CArchive& ar)
{
CPainted::Serialize(ar);
if (ar.IsStoring())
{
ar << m_pointEnd;
ar << m_angStart;
}
else
{
ar >> m_pointEnd;
ar >> m_angStart;
}
}
void CPaintScp::toChar(char *p_Char)
{
}
char * CPaintScp::toData(char *p_Char)
{
return p_Char; //返回指向成员变量的字符串后的位置
}
void CPaintScp::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;
}
//LAZY-S曲线方程
//参数定义:fX为实时的X轴坐标,返回值为实时的Y轴坐标
//m_fXe为曲线在X轴方向上的宽度(终点-起点)
//m_fYe为曲线在Y轴方向上的宽度(终点-起点),m_fYe为正时为标准形状
//m_fYe为负时为标准形状的镜相
double CPaintScp::calculate(double fX,double m_fXe,double m_fYe)
{
double fRate = fX / m_fXe;
return m_fYe*fRate*fRate*fRate*(10-fRate*(15-6*fRate));
}
//LAZY-S曲线近似方程
//参数定义:x为实时的X轴坐标,y为实时的Y轴坐标
//mm为曲线在X轴方向上的宽度
//nn为曲线在Y轴方向上的宽度
//y=(sin(x*pi/mm-pi/2)*nn/2+nn/2);
//返回路段给定端点的姿态角(外射角)
double CPaintScp::ReturnPostureAngle(UINT id)
{
double angle;
if(m_uStartNodeId==id)
angle=m_StartPostureAngle;
else
angle=m_EndPostureAngle;
return angle;
}
void CPaintScp::GetPostureAngle()//计算得到路段的姿态角(外射角)
{
m_StartPostureAngle=m_angStart;
m_EndPostureAngle=m_angStart;
}
//就近点判断函数,pnt1为鼠标点坐标,id为返回点的ID,pnt为返回点的坐标,angle为返回点的姿态角
//此函数只用于得到路径的起点!!
//返回值为TRUE表示有就近点,FALSE表示无就近点
BOOL CPaintScp::NearJudge1(CPnt pnt1,UINT& id,CPnt& pnt,double& angle)
{
BOOL forreturn=FALSE;
if(m_pDoc->m_nGraphSelect==1&&m_bSelect==TRUE)//若为参考线段
{
if(!m_bReferencePoint)//参考点为终点
{
pnt.x=m_pointEnd.x;
pnt.y=m_pointEnd.y;
angle=m_EndPostureAngle;
id=m_uEndNodeId;
forreturn=TRUE;
}
else//参考点为起点
{
pnt.x=m_pointPrimary.x;
pnt.y=m_pointPrimary.y;
angle=m_StartPostureAngle;
id=m_uStartNodeId;
forreturn=TRUE;
}
}
else//若不为参考线段
{
CPoint pointPrimary1,pointEnd1,point1;
DPtoVP(m_pointPrimary,pointPrimary1);
DPtoVP(m_pointEnd,pointEnd1);
DPtoVP(pnt1,point1);
if(Distance(point1.x,point1.y,pointPrimary1.x,pointPrimary1.y)<5)
{
pnt.x=m_pointPrimary.x;
pnt.y=m_pointPrimary.y;
angle=m_StartPostureAngle;
id=m_uStartNodeId;
forreturn=TRUE;
}
else if(Distance(point1.x,point1.y,pointEnd1.x,pointEnd1.y)<5)
{
pnt.x=m_pointEnd.x;
pnt.y=m_pointEnd.y;
angle=m_EndPostureAngle;
id=m_uEndNodeId;
forreturn=TRUE;
}
}
return forreturn;
}
//就近点判断函数,
//pnt1为鼠标点坐标或计算得到的准终点坐标,
//id为返回点的ID,pnt为返回点的坐标,angle为返回点的姿态角
//此函数只用于得到路径的终点!!
//返回值为TRUE表示有就近点,FALSE表示无就近点
//当GetPathEndnode()函数调用此函数时
//应根据是否满足相切条件来决定此函数返回数据的取舍
BOOL CPaintScp::NearJudge2(CPnt pnt1,UINT& id,CPnt& pnt,double& angle)
{
BOOL forreturn=FALSE;
CPoint pointPrimary1,pointEnd1,point1;
DPtoVP(m_pointPrimary,pointPrimary1);
DPtoVP(m_pointEnd,pointEnd1);
DPtoVP(pnt1,point1);
if(Distance(point1.x,point1.y,pointPrimary1.x,pointPrimary1.y)<5)
{
pnt.x=m_pointPrimary.x;
pnt.y=m_pointPrimary.y;
angle=m_StartPostureAngle;
id=m_uStartNodeId;
forreturn=TRUE;
}
else if(Distance(point1.x,point1.y,pointEnd1.x,pointEnd1.y)<5)
{
pnt.x=m_pointEnd.x;
pnt.y=m_pointEnd.y;
angle=m_EndPostureAngle;
id=m_uEndNodeId;
forreturn=TRUE;
}
return forreturn;
}
//坐标变换
//从曲线的自身坐标系-》逻辑坐标系
//参数说明如下:
//m_pntStart:曲线在逻辑坐标系中起点坐标
//2*pi-m_angStart:起点的倾斜角(与逻辑坐标系X轴正向夹角)
//pnt:自身坐标系中某点的坐标
//point:某点经坐标变换后得到该点在逻辑坐标系中的坐标
void CPaintScp::Transform(CPnt pnt,CPnt& point)
{
CPnt m_pntStart;
DPtoVPf(m_pointPrimary,m_pntStart);
point.x=m_pntStart.x+pnt.x*cos(2*pi-m_angStart)-pnt.y*sin(2*pi-m_angStart);
point.y=m_pntStart.y+pnt.x*sin(2*pi-m_angStart)+pnt.y*cos(2*pi-m_angStart);
}
//坐标变换
//从逻辑坐标系-》曲线的自身坐标系
void CPaintScp::Transform1(CPnt pnt,CPnt& point)
{
CPnt m_pntStart;
DPtoVPf(m_pointPrimary,m_pntStart);
point.x=(pnt.x-m_pntStart.x)*cos(2*pi-m_angStart)+(pnt.y-m_pntStart.y)*sin(2*pi-m_angStart);
point.y=(m_pntStart.x-pnt.x)*sin(2*pi-m_angStart)-(m_pntStart.y-pnt.y)*cos(2*pi-m_angStart);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -