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

📄 paintscp.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -