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

📄 arctool.cpp

📁 参数化车间设备资源绘制程序
💻 CPP
字号:
#include "StdAfx.h"
#include ".\arctool.h"

#include <math.h>

#include "arcobj.h"
#include "visdrawdoc.h"
#include "visdrawview.h"


CArcTool::CArcTool(void)
{
}

CArcTool::~CArcTool(void)
{
}

CArcTool::CArcTool(DrawShape drawShape)
	: CDrawTool(drawShape)
{
	pObj = NULL;
}

void CArcTool::OnLButtonDown(CVisDrawView* pView, UINT nFlags, const CPoint& point)
{	
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CPoint dp;
	double ptx, pty;
	double nCenterPointx, nCenterPointy;

	CPoint local = point;

	//把设备坐标转化为逻辑坐标
	pView->ClientToDoc(local);

	//点point的世界坐标ptx,pty
	pView->ClientToWorld(local, ptx,pty);

	m_LMouseDownStep++;

	//申请与视图窗口相关的设备描述表
	CDC* dc=pView->GetDC();

	//设定屏幕反色绘图模式
	dc->SetROP2(R2_NOT);

	//根据按下鼠标的次数执行不同的操作
	switch(m_LMouseDownStep)
	{
	default:
		ASSERT(FALSE); 
	case 1:

		//第一次鼠标按下时创建CArcObj对象

		pObj = new CArcObj(CRect(local, CSize(0, 0)));	
		
		//第一次按下鼠标时三种画弧工具的其他任务
		switch(m_drawShape)
		{
		default:
			break;
		case tparcTool:				//弧上三点画弧工具	       

		case secarcTool:			//起点、终点、圆心画弧工具	
			break;
		case csearcTool:			//圆心、起点、终点画弧工具
			
			//把第一个点指定为圆心			
            pObj->SetCenterPoint(ptx,pty);

			break;
		}

		//把CArcObj对象指针加到文档对象指针链表中
		pView->GetDocument()->Add(pObj);

		//记录辅助点
        
		//第一次按下的设备坐标点
		lastPoint = point;
		prePoint = point;
		oldPoint = point;
		
		//第一次按下的逻辑坐标点
		flocal = local;
		break;
	case 2:
		//第二次按下鼠标时三种画弧工具的任务
		
		switch(m_drawShape)
		{
		default:
			break;
		case tparcTool:			//弧上三点画弧工具
			
			//删除第一点到第二点之间的直线(在鼠标移动消息中绘制的)
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);	
			
			break;
		case secarcTool:		//起点、终点、圆心画弧工具
			
			//以第一点到第二点之间的距离为直径	
			dp = local - flocal;

			double radium;

			//计算逻辑半径
			radium = sqrt((double)(dp.x*dp.x + dp.y*dp.y))/2.0;

			//计算世界坐标下的半径
			radium = pView->ClientToWorld(radium);

			//设定圆弧对象半径
			pObj->SetRadium(radium);
            			
			//以第一点和第二点的中点为圆心
			dp.x = (flocal.x + local.x)/2;
			dp.y = (flocal.y + local.y)/2;

			//把圆心转化为世界坐标
			pView->ClientToWorld(dp,nCenterPointx, nCenterPointy);

			//设定圆弧对象圆心
			pObj->SetCenterPoint(nCenterPointx, nCenterPointy);

			//计算起点、终点弧度		
			pObj->SetStartAngle(pObj->CalcArcAngle(pView,flocal));		
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,local));

			break;
		case csearcTool:					//圆心、起点、终点画弧工具
			
			//计算半径
			pObj->SetRadium(pObj->CalcRadium(ptx,pty));
			
			//计算起点弧度
			pObj->SetStartAngle(pObj->CalcArcAngle(pView,local));			
			break;
		}
		prePoint = point;
		oldPoint = point;
		tlocal = local;
		prelocal = local;
		break;
	case 3:
		//第三次按下鼠标左键
		switch(m_drawShape)
		{
		default:
			break;
		case tparcTool:			//弧上三点画弧工具

			//由弧上三点计算圆弧参数
			pObj->CalculateArcParameterbytp(pView,flocal,tlocal,local);		
		//	dc->SetROP2(R2_COPYPEN);
		//	DrawArc(pView, dc,pObj);
			break;
		case secarcTool:		//起点、终点、圆心画弧工具
		
			//第三点为圆心,为世界坐标
			pView->ClientToWorld(local,nCenterPointx, nCenterPointy);
			pObj->SetCenterPoint(nCenterPointx, nCenterPointy);

			//圆心变化后需要重新计算起点和终点的弧度

			//计算起点弧度
			pObj->SetStartAngle(pObj->CalcArcAngle(pView,flocal));

			//计算终点弧度
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,tlocal));

			break;
		case csearcTool:		//圆心、起点、终点画弧工具

			//删除从圆心到起点鼠标点之间的直线
		//	dc->MoveTo(lastPoint);
		//	dc->LineTo(oldPoint);	

			//计算终点弧度
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,local));
			break;
		}

		//计算圆弧外接矩形
		pObj->CalcBounds(pView);	

		//把鼠标按下次数标记置0
		m_LMouseDownStep = 0;

		//刷新视图
		pView->Invalidate(TRUE);

		//对象指针
		pObj = NULL;
		break;		
	}	

	//删除设备描述表
	pView->ReleaseDC(dc);
}

void CArcTool::OnLButtonUp(CVisDrawView* pView, UINT nFlags, const CPoint& point)
{
	
}

void CArcTool::OnMouseMove(CVisDrawView* pView, UINT nFlags, const CPoint& point)
{
	
	double nCenterPointx, nCenterPointy;	//圆弧圆心

	CPoint local = point;
	
	//把设备坐标转化为逻辑坐标
	pView->ClientToDoc(local);	

	if(!m_LMouseDownStep) return;
	
	//申请与视图窗口相关的设备描述表
	CDC* dc=pView->GetDC();

	//用屏幕颜色的反色绘图
	dc->SetROP2(R2_NOT);	

	switch(m_LMouseDownStep)
	{
	case 1:			
		
		//第一次按下鼠标时三种画弧工具的其他任务
		switch(m_drawShape)
		{
		default:
			break;
		case tparcTool:				//弧上三点画弧工具

			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);
				
			//绘制第一点到当前鼠标点位置的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(point);
			break;
			
		case secarcTool:			//起点、终点、圆心画弧工具

			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);
				
			//绘制起点到当前鼠标点位置的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(point);
			break;
		case csearcTool:			//圆心、起点、终点画弧工具
			
			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);
				
			//绘制起点到当前鼠标点位置的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(point);
			break;
		}		
		break;
	case 2:

		//第一次按下鼠标时三种画弧工具的其他任务
		switch(m_drawShape)
		{
		default:
			break;
		case tparcTool:				//弧上三点画弧工具	

			//删除第二点与第三点重合时所画的圆弧		
			if(tlocal == prelocal)
			{
				pObj->CalculateArcParameterbytp(pView,flocal,tlocal,prelocal);
				DrawArc(pView, dc,pObj);
			}

			
			//删除前经过前一个鼠标点的圆弧
			pObj->CalculateArcParameterbytp(pView,flocal,tlocal,prelocal);
			DrawArc(pView, dc,pObj);

			//绘制经过当前鼠标点的圆弧
			pObj->CalculateArcParameterbytp(pView,flocal,tlocal,local);
			DrawArc(pView, dc,pObj);
		

			break;
			
		case secarcTool:			//起点、终点、圆心画弧工具	

			///////////////////////////////////////////////////////////////////
			
			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);
				
			//绘制起点到当前鼠标点位置的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(point);

			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(oldPoint);
			dc->LineTo(prePoint);
				
			//绘制起点到当前鼠标点位置的直线
			dc->MoveTo(oldPoint);
			dc->LineTo(point);

			/////////////////////////////////////////////////////////////////

			//删除起点与终点重合时所画的圆弧
			if(tlocal == prelocal)
			{
				
				//计算以前一个鼠标点为圆心的坐标
				pView->ClientToWorld(prelocal,nCenterPointx, nCenterPointy);
				pObj->SetCenterPoint(nCenterPointx, nCenterPointy);
				
				//计算以前一个鼠标点为圆心的起点和重点弧度

				//计算起点和终点弧度
				pObj->SetStartAngle(pObj->CalcArcAngle(pView,flocal));
				pObj->SetEndAngle(pObj->CalcArcAngle(pView,tlocal));

				//删除以前一个鼠标点为圆心的圆弧
				DrawArc(pView, dc,pObj);
			}

			/////////////////////////////////////////////////////////////////

			//计算以前一个鼠标点为圆心的坐标
			pView->ClientToWorld(prelocal,nCenterPointx, nCenterPointy);
			pObj->SetCenterPoint(nCenterPointx, nCenterPointy);
			
			//计算以前一个鼠标点为圆心的起点和重点弧度

			//计算起点和终点弧度
			pObj->SetStartAngle(pObj->CalcArcAngle(pView,flocal));
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,tlocal));

			//删除以前一个鼠标点为圆心的圆弧
			DrawArc(pView, dc,pObj);
		
			//////////////////////////////////////////////////////////////

			//计算以当前鼠标点为圆心的坐标
			pView->ClientToWorld(local,nCenterPointx, nCenterPointy);
			pObj->SetCenterPoint(nCenterPointx, nCenterPointy);

			//计算以当前鼠标点为圆心的起点和重点弧度

			//计算起点和终点弧度
			pObj->SetStartAngle(pObj->CalcArcAngle(pView,flocal));
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,tlocal));

			//绘制以当前鼠标点为圆心的圆弧
			DrawArc(pView, dc,pObj);
			break;
		case csearcTool:			//圆心、起点、终点画弧

			//删除第一点到前一个鼠标位置点之间的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(prePoint);	

            //绘制起点到当前鼠标点位置的直线
			dc->MoveTo(lastPoint);
			dc->LineTo(point);		

			//删除起点与终点重合时所画的圆弧
			if(tlocal == prelocal)
			{
				pObj->SetEndAngle(pObj->CalcArcAngle(pView, prelocal));
				DrawArc(pView, dc,pObj);
			}
			
			//删除以前一个鼠标点为终点的圆弧
			pObj->SetEndAngle(pObj->CalcArcAngle(pView, prelocal));
			DrawArc(pView, dc,pObj);

			//画以当前鼠标点为终点的圆弧
			pObj->SetEndAngle(pObj->CalcArcAngle(pView,local));
			DrawArc(pView, dc,pObj);
			break;
		}
		break;
	case 3:		
		break;
	}	

	//记录前一个鼠标点的逻辑坐标
	prelocal = local;

	//记录前一个鼠标点的设备坐标
	prePoint = point;

	pView->ReleaseDC(dc);
}

void CArcTool::OnLButtonDblClk(CVisDrawView* pView, UINT nFlags, const CPoint& point)
{
}

void CArcTool::CreateObj(CVisDrawView* pView, const CPoint& point)
{
	
}


//采用设备坐标绘制圆弧
void CArcTool::DrawArc(CVisDrawView* pView, CDC* dc,CArcObj* pObj)
{
	double nCenterPointx, nCenterPointy;
	double x1,y1,x2,y2;
	CPoint nCenterPoint;
	double nRadium;
	double StartAngle,EndAngle;

	//获得圆心世界坐标
	pObj->GetCenterPoint(nCenterPointx, nCenterPointy);

	//把圆心世界坐标转化为逻辑坐标
	pView->WorldToClient(nCenterPoint,nCenterPointx, nCenterPointy);

	//把圆心转化为设备坐标
	pView->DocToClient(nCenterPoint);

    //世界坐标下的圆弧半径
	nRadium = pObj->GetRadium();

	//圆弧起点、终点弧度
	StartAngle = pObj->GetStartAngle();
	EndAngle = pObj->GetEndAngle();

	//得到起点坐标
	x1=nCenterPointx +nRadium*cos(StartAngle);
	y1=nCenterPointy +nRadium*sin(StartAngle);

	//得到终点的坐标
	x2=nCenterPointx +nRadium*cos(EndAngle);
	y2=nCenterPointy +nRadium*sin(EndAngle);
	
	//把起点、终点转化为逻辑坐标
	CPoint nStart, nEnd;
	pView->WorldToClient(nStart,x1,y1);
	pView->WorldToClient(nEnd,x2,y2);

	//把起点、终点转化为设备坐标
	pView->DocToClient(nStart);
	pView->DocToClient(nEnd);

	//把半径转化为逻辑(设备)半径
	nRadium = pView->WorldToClient(nRadium);

	//采用设备坐标画圆弧
	dc->Arc((nCenterPoint.x - (long)nRadium),(nCenterPoint.y + (long)nRadium),
		(nCenterPoint.x + (long)nRadium),(nCenterPoint.y - (long)nRadium),
		nStart.x,nStart.y,nEnd.x,nEnd.y);

}

⌨️ 快捷键说明

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