www.pudn.com > VCad3.0.zip > Line.cpp


#include "stdafx.h" 
#include "math.h" 
#include "VCad.h" 
#include "VCadDoc.h" 
#include "VCadView.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); 
}