📄 polyobj.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 + -