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

📄 polyobj.cpp

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

//#include <math.h>

IMPLEMENT_SERIAL(CPolyObj, CFigureObj, 0)



CFloatPoint::CFloatPoint(void)
{
	pointx = 0.0;
	pointy = 0.0;
}

CFloatPoint::~CFloatPoint(void)
{
}

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

CPolyObj::CPolyObj(void)
{
}

CPolyObj::~CPolyObj(void)
{
	//if (m_points != NULL)
	//	delete[] m_points;

	if(m_floatpoints != NULL)
		delete[] m_floatpoints;
}

CPolyObj::CPolyObj(const CRect& position)
		: CFigureObj(position)
{
	ASSERT_VALID(this);	
	m_nShape = polygonshape;
	m_points = NULL;
	m_floatpoints = NULL;
	m_nPoints = 0;
	m_nAllocPoints = 0;
}

void CPolyObj::Serialize(CArchive& ar)
{
	ASSERT_VALID(this);
	int i;
	//调用基类串行化
	CFigureObj::Serialize( ar );

	if( ar.IsStoring() )
	{
		ar << (WORD) m_nShape;
		ar << (WORD) m_nPoints;
		ar << (WORD) m_nAllocPoints;
		for (i = 0;i< m_nPoints; i++)
			ar << m_floatpoints[i].pointx << m_floatpoints[i].pointy;
	}
	else
	{
		WORD wTemp;
		ar >> wTemp; m_nShape = (Shape)wTemp;
		ar >> wTemp; m_nPoints = wTemp;
		ar >> wTemp; m_nAllocPoints = wTemp;
		m_floatpoints = new CFloatPoint[m_nAllocPoints];
		for (i = 0;i < m_nPoints; i++)
			ar >> m_floatpoints[i].pointx >> m_floatpoints[i].pointy;
	}
}

void CPolyObj::Draw(CVisDrawView* pView, CDC* pDC)
{
	ASSERT_VALID(this);

	CBrush brush;
	if (!brush.CreateBrushIndirect(&m_logbrush))
		return;
	CPen pen;
	if (!pen.CreatePenIndirect(&m_logpen))
		return;

	CBrush* pOldBrush;
	CPen* pOldPen;

	if (m_bBrush)
		pOldBrush = pDC->SelectObject(&brush);
	else
		pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);

	if (m_bPen)
		pOldPen = pDC->SelectObject(&pen);
	else
		pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN);


	//创建一个临时CPoint对象数组,保存多边形逻辑顶点逻辑坐标
	CPoint* m_points = new CPoint[m_nPoints];
		
	double ptx,pty;
	CPoint pt;

	//把所有顶点的世界坐标转化为逻辑坐标
	for(int i = 0;i<m_nPoints;i++)
	{
		ptx = m_floatpoints[i].pointx;
		pty = m_floatpoints[i].pointy;
		pView->WorldToClient(pt,ptx,pty);
		m_points[i].x=pt.x;
		m_points[i].y =pt.y;

	}	
	
	switch(m_nShape)
	{
	case polygonshape:		//绘制多边形

		pDC->Polygon(m_points, m_nPoints);
		break;

	case polylineshape:		//绘制多边线

		pDC->Polyline(m_points, m_nPoints);
		break;
	}

	//删除临时顶点数组
	delete[] m_points;

	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);
}

//计算多边形图形元边界矩形,以逻辑坐标表示
CRect CPolyObj::CalcBounds(CVisDrawView* pView)
{
	ASSERT_VALID(this);

	//创建临时顶点逻辑坐标数组
	CPoint* m_points = new CPoint[m_nPoints];
		
	double ptx,pty;
	CPoint pt;

	//把所有顶点的世界坐标转化为逻辑坐标
	for(int i = 0;i<m_nPoints;i++)
	{
		ptx = m_floatpoints[i].pointx;
		pty = m_floatpoints[i].pointy;
		pView->WorldToClient(pt,ptx,pty);
		m_points[i].x=pt.x;
		m_points[i].y =pt.y;

	}	

	//找出所有顶点中x,y的最大与最小值,并由矩形对象bounds保存
	CRect bounds(m_points[0], CSize(0, 0));
	for (int i = 1; i < m_nPoints; ++i)
	{
		if (m_points[i].x < bounds.left)
			bounds.left = m_points[i].x;
		if (m_points[i].x > bounds.right)
			bounds.right = m_points[i].x;
		if (m_points[i].y < bounds.top)
			bounds.top = m_points[i].y;
		if (m_points[i].y > bounds.bottom)
			bounds.bottom = m_points[i].y;
	}
	
	//删除临时顶点数组
	delete[] m_points;

	//保存多边形边界矩形
	m_position = bounds;
	
	return bounds;

}

//添加多边形节点
void CPolyObj::AddPoint(const CPoint& point, CVisDrawView* pView)
{
	ASSERT_VALID(this);

	//参数point是逻辑坐标,需要转化为实际坐标
	double ptx,pty;
	pView->ClientToWorld(point,ptx,pty);

	//动态创建数组
	if (m_nPoints == m_nAllocPoints)
	{
	
		CFloatPoint* newfloatPoints = new CFloatPoint[m_nAllocPoints + 1];
		if (m_floatpoints != NULL)
		{
			memcpy(newfloatPoints, m_floatpoints, sizeof(CFloatPoint) * m_nAllocPoints);
			delete[] m_floatpoints;
		}
		m_floatpoints = newfloatPoints;
		
		m_nAllocPoints += 1;
	}

	//如果是第一个顶点或不重合的顶点,添加到数组中去
	if(m_nPoints == 0 ||((m_floatpoints[m_nPoints - 1].pointx != ptx)
		&&(m_floatpoints[m_nPoints - 1].pointy != pty)))
	{
		m_floatpoints[m_nPoints].pointx = ptx;
		m_floatpoints[m_nPoints].pointy = pty;
		m_nPoints++;

		//如果顶点数不为0,计算多边形边界矩形
		if(m_nPoints != 0)
		CalcBounds(pView);

		//修改文档标致
        pView->GetDocument()->SetModifiedFlag();
	}
	
}

//返回手柄个数
int CPolyObj::GetHandleCount()
{
	ASSERT_VALID(this);

	return m_nPoints;
}

// 返回手柄中心逻辑坐标
CPoint CPolyObj::GetHandle(CVisDrawView* pView, int nHandle)
{
	ASSERT_VALID(this);
	
	ASSERT(nHandle >= 1 && nHandle <= m_nPoints);

	double ptx,pty;
	CPoint pt;
	
	//把顶点世界坐标转化为逻辑坐标
	ptx = m_floatpoints[nHandle - 1].pointx;
	pty = m_floatpoints[nHandle - 1].pointy;
	pView->WorldToClient(pt,ptx,pty);
	
	return pt;
}
//移动手柄
void CPolyObj::MoveHandleTo(int nHandle, CPoint point, CVisDrawView* pView)
{
	ASSERT_VALID(this);
	ASSERT(nHandle >= 1 && nHandle <= m_nPoints);

	//把鼠标逻辑坐标转化为世界坐标
	double pointx,pointy;
	pView->ClientToWorld(point,pointx,pointy);

	if (m_floatpoints[nHandle - 1].pointx == pointx &&
		m_floatpoints[nHandle - 1].pointy == pointy)
		return;	

	m_floatpoints[nHandle - 1].pointx = pointx;
	m_floatpoints[nHandle - 1].pointy = pointy;

	CalcBounds(pView);
}

// delta为逻辑坐标
void CPolyObj::MoveTo(CPoint delta, CVisDrawView* pView)
{
	ASSERT_VALID(this);	
	//把delta转化为世界坐标
	double pointx,pointy;
	pointx = pView->ClientToWorld(delta.x);
	pointy = -pView->ClientToWorld(delta.y);


	//修改所有顶点坐标
//	double ptx,pty;
//	CPoint pt;

	//把所有顶点的世界坐标转化为逻辑坐标
	for(int i = 0;i<m_nPoints;i++)
	{
		m_floatpoints[i].pointx += pointx;
		m_floatpoints[i].pointy += pointy;
	}	

	//重新计算边界矩形
	CalcBounds(pView);

	//修改文档标志	
	m_pDocument->SetModifiedFlag();
}
//BOOL CPolyObj::IsSelected(CVisDrawView* pView,const CPoint& point)
//{
  // ASSERT_VALID(this);

	//参数point是鼠标的逻辑坐标
	//double distance,ptx,pty;
	//int nSelectDistance;

	//CPoint local,StartPoint,EndPoint;
	//local = point;
	//鼠标点的设备坐标
	//pView->DocToClient(local);

	//识别精度值
	//nSelectDistance = pView->GetDocument()->GetSetectDistance()/2;
	
	//平移所有顶点坐标
	//for(int i=0;i<m_nPoints;i++)
	//{
	//	int j=i+1;
	//	if(j==m_nPoints) j=0;

		//把顶点实际坐标转化为逻辑坐标
	//	ptx=m_floatpoints[i].pointx;
    //    pty=m_floatpoints[i].pointy;
	//	pView->WorldToClient(StartPoint,ptx,pty);

		//把顶点实际坐标转化为逻辑坐标
	//	ptx=m_floatpoints[i].pointx;
    //    pty=m_floatpoints[i].pointy;
	//	pView->WorldToClient(EndPoint,ptx,pty);

	//	pView->DocToClient(StartPoint);
	//	pView->DocToClient(EndPoint);

		//鼠标点到直线的距离
    //   distance =(int)PointToLine(StartPoint,EndPoint,local);
	   //根据拾取条件判断图元是否被拾取
	//   if(distance < nSelectDistance)
	//    return TRUE;
	//}
	//return false;

	
//}

//double CPolyObj::PointToLine(CPoint nStartPt, CPoint nEndPt, CPoint pt)
//{
	//int A,B,C;
	//double distance;

	//计算直线参数
	//A = nStartPt.y - nEndPt.y;
	//B = nEndPt.x - nStartPt.x;
	//C = nStartPt.x*nEndPt.y - nEndPt.x*nStartPt.y;

	//计算点到直线距离
	//distance = (A*pt.x + B*pt.y + C)*(A*pt.x + B*pt.y + C)/(A*A + B*B);
	//distance = sqrt(distance);
	//return distance;
//}

⌨️ 快捷键说明

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