📄 line.cpp
字号:
#include "stdafx.h"
#include "math.h"
#include "MyPaint.h"
#include "MyPaintDoc.h"
#include "MyPaintView.h"
#include "Entity.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CLine, CEntity, 0)
CLine::CLine()
{
Init();
}
CLine::CLine(const CLine& line)
: CEntity(line)
{
m_begin = line.m_begin;
m_end = line.m_end;
}
CLine::CLine(const Position& begin,const Position& end)
{
Init();
m_begin = begin ;
m_end = end ;
}
CLine::~CLine()
{
}
CLine& CLine::operator = (const CLine& line)
{
// 处理特殊情况:line1 = line1
if(this == &line)
return *this;
// 一般情形:line2 = line1
CEntity::operator = (line); // 调用基类的重载“=”操作
m_begin = line.m_begin;
m_end = line.m_end;
return *this;
}
CEntity* CLine::Copy()
{
CLine* pEntity = new CLine(m_begin, m_end);
return pEntity;
}
void CLine::Init()
{
CEntity::Init();
m_type = etLine;
m_begin.Init();
m_end.Init();
}
int CLine::GetType()
{
return etLine;
}
Position CLine::GetBeginPos()
{
return m_begin;
}
Position CLine::GetEndPos()
{
return m_end;
}
void CLine::Draw(CDC * pDC, int drawMode /* = dmNormal */)
{
CPoint pt_begin, pt_end; // 屏幕坐标的起点和终点
g_pView->WorldtoScreen(m_begin,pt_begin); // 将世界坐标转化为屏幕坐标
g_pView->WorldtoScreen(m_end,pt_end) ;
int n = GetROP2(pDC->GetSafeHdc()); // 得到原来的绘图模式
CPen pen;
if( drawMode == dmNormal ) // 如果为正常状态的绘制,根据成员变量创建画笔
pen.CreatePen(m_lineStyle,m_lineWidth,m_color) ;
else // 非正常状态调用SetDrawEnvir函数设置绘图环境
::SetDrawEnvir(pDC, drawMode, &pen);
CPen* pOldPen = pDC->SelectObject(&pen); // 得到原来的画笔
pDC->SetMapMode(MM_LOENGLISH);
pDC->MoveTo(pt_begin); // 根据屏幕坐标绘制图元
pDC->LineTo(pt_end);
pDC->SelectObject(pOldPen); // 恢复原来的画笔
pDC->SetROP2(n); // 恢复原来的绘图模式
}
BOOL CLine::Pick(const Position& pos, const double pick_radius)
{
Position objPos = pos;
BOX2D sourceBox,desBox;
GetBox(&sourceBox); // 得到直线段的最小包围盒
// 将最小包围盒向四周放大,得到测试包围盒
desBox.min[0] = sourceBox.min[0] - pick_radius;
desBox.min[1] = sourceBox.min[1] - pick_radius;
desBox.max[0] = sourceBox.max[0] + pick_radius;
desBox.max[1] = sourceBox.max[1] + pick_radius;
// 判断拾取点是否在测试包围盒中,如果不是,则图元未被选中
if( !objPos.IsInBox(desBox) )
return FALSE;
double angle = ::GetAngleToXAxis(m_begin,m_end);
// DIST = fabs(X * cos(a) + Y * sin(a) - P)
Position dp = objPos - m_begin;
double dist = fabs(dp.x*cos(angle) + dp.y*sin(angle) - objPos.Distance(m_begin));
if(dist <= pick_radius)
return TRUE;
return FALSE;
}
void CLine::GetBox(BOX2D* pBox)
{
pBox->min[0] = min( m_begin.x, m_end.x );
pBox->min[1] = min( m_begin.y, m_end.y );
pBox->max[0] = max( m_begin.x, m_end.x );
pBox->max[1] = max( m_begin.y, m_end.y );
}
void CLine::Move(const Position& basePos,const Position& desPos)
{
m_begin = m_begin.Offset(desPos - basePos);
m_end = m_end.Offset(desPos - basePos);
}
void CLine::Rotate(const Position& basePos, const double angle)
{
m_begin = m_begin.Rotate(basePos, angle) ;
m_end =m_end.Rotate(basePos, angle) ;
}
void CLine::Mirror(const Position& pos1, const Position& pos2)
{
m_begin = m_begin.Mirror(pos1, pos2) ;
m_end =m_end.Mirror(pos1, pos2) ;
}
void CLine::LoadPmtCursor()
{
// ::SetCursor(AfxGetApp()->LoadCursor(IDC_PROMPT_LINE));
}
BOOL CLine::GetSnapPos(Position& pos)
{
BOOL ret = FALSE;
Position p[3]; // feature position: start pt, end pt, mid pt
p[0] = m_begin;
p[1] = m_end;
p[2] = (p[0] + p[1]) * 0.5;
for( int i=0; i<3; i++ ){
if( pos.Distance(p[i]) < 0.5 ){
pos = p[i];
ret = TRUE;
break;
}
}
return ret;
}
void CLine::Serialize(CArchive& ar)
{
CEntity::Serialize(ar);
m_begin.Serialize(ar);
m_end.Serialize(ar);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -