?? rectobj.cpp
字號:
//rectobj.cpp 矩形類的實現文檔
#include "StdAfx.h"
#include ".\rectobj.h"
#include "visdrawview.h"
#include "visdrawdoc.h"
#include <math.h>
IMPLEMENT_SERIAL(CRectObj, CFigureObj, 0)
CRectObj::CRectObj(void)
{
}
CRectObj::~CRectObj(void)
{
}
CRectObj::CRectObj(const CRect& position)
: CFigureObj(position)
{
ASSERT_VALID(this);
m_nShape=lineshape;
m_ltx=0.0;m_lty=0.0;m_rbx=0.0;m_rby=0.0;
}
void CRectObj::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 m_ltPoint, m_rbPoint;
CRect rect = CalcBounds(pView);
switch (m_nShape)
{
case rectshape: //繪制矩形圖元
pDC->Rectangle(rect);
break;
case lineshape: //繪制直線圖元
pDC->MoveTo(rect.TopLeft());
pDC->LineTo(rect.BottomRight());
break;
}
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
void CRectObj::Serialize(CArchive& ar)
{
ASSERT_VALID(this);
//調用基類串行化
CFigureObj::Serialize(ar);
if (ar.IsStoring())
{
ar << (WORD) m_nShape;
ar << m_ltx << m_lty << m_rbx << m_rby;
}
else
{
WORD wTemp;
ar >> wTemp; m_nShape = (Shape)wTemp;
ar >> m_ltx >> m_lty >> m_rbx >> m_rby;
}
}
//設定直線端點坐標,為世界坐標
void CRectObj::SetPoint(int ptNumber, double x, double y)
{
ASSERT(ptNumber <=2);
switch(ptNumber)
{
case 1:
m_ltx = x;
m_lty = y;
break;
case 2:
m_rbx = x;
m_rby = y;
break;
}
}
//返回直線端點的世界坐標
void CRectObj::GetPoint(int ptNumber, double& x, double& y)
{
ASSERT(ptNumber <=2);
switch(ptNumber)
{
case 1:
x = m_ltx;
y = m_lty;
break;
case 2:
x = m_rbx;
y = m_rby;
break;
}
}
//計算外接矩形,以邏輯坐標表示
CRect CRectObj::CalcBounds(CVisDrawView* pView)
{
CRect rect;
CPoint ltPoint, rbPoint;
pView->WorldToClient(ltPoint,m_ltx,m_lty);
pView->WorldToClient(rbPoint,m_rbx,m_rby);
rect.TopLeft() = ltPoint;
rect.BottomRight() = rbPoint;
m_position = rect;
return rect;
}
double CRectObj::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;
}
BOOL CRectObj::IsSelected(CVisDrawView* pView, const CPoint& point)
{
CPoint local, StartPt, EndPt;
int distance, nSelectDistance;
local = point;
CRect rect = m_position;
//矩形設備坐標
pView->DocToClient(rect);
//識別精度值
nSelectDistance = pView->GetDocument()->GetSetectDistance()/2;
//鼠標點的設備坐標
pView->DocToClient(local);
switch (m_nShape)
{
case rectshape: //繪制矩形圖元
//第一條直線
distance = abs(local.y - rect.top);
if(distance < nSelectDistance) return true;
//第二條直線
distance = abs(local.x - rect.right);
if(distance < nSelectDistance) return true;
//第三條直線
distance = abs(local.y - rect.bottom);
if(distance < nSelectDistance) return true;
//第四條直線
distance = abs(local.x - rect.left);
if(distance < nSelectDistance) return true;
break;
case lineshape: //繪制直線圖元
StartPt = rect.TopLeft();
EndPt = rect.BottomRight();
//鼠標點到直線距離
distance = (int)PointToLine(StartPt, EndPt, local);
//根據拾取條件判斷圖元是否被拾取
return (distance < nSelectDistance);
break;
}
return false;
}
//返回手柄個數
int CRectObj::GetHandleCount()
{
ASSERT_VALID(this);
//如果圖元類型為直線,手柄個數為3個
//否則圖元為矩形,手柄個數調用基類成員函數得到
return m_nShape == lineshape ?3 :
CFigureObj::GetHandleCount() ;
}
// 返回手柄中心邏輯坐標
CPoint CRectObj::GetHandle(CVisDrawView* pView, int nHandle)
{
ASSERT_VALID(this);
//如果圖元類型為直線
if(m_nShape == lineshape)
{
//圖元直線1、2、3號手柄相當于基類中1、5、9號手柄
switch(nHandle)
{
case 2:
nHandle = 5;
break;
case 3:
nHandle = 9;
break;
}
}
//調整手柄號后調用基類成員函數
return CFigureObj::GetHandle(pView, nHandle);
}
// point 為邏輯坐標
void CRectObj::MoveHandleTo(int nHandle, CPoint point, CVisDrawView* pView)
{
ASSERT_VALID(this);
//把鼠標邏輯坐標轉化為世界坐標
double pointx,pointy;
pView->ClientToWorld(point,pointx,pointy);
//如果圖元類型為直線
if(m_nShape == lineshape)
{
//圖元直線1、2、3號手柄相當于基類中1、5、9號手柄
switch(nHandle)
{
case 2:
nHandle = 5;
break;
case 3:
nHandle = 9;
break;
}
}
switch (nHandle)
{
default:
ASSERT(FALSE);
case 1:
SetPoint(1,pointx,pointy);
break;
case 2:
SetPoint(1,m_ltx,pointy);
break;
case 3:
SetPoint(1,m_ltx,pointy);
SetPoint(2,pointx,m_rby);
break;
case 4:
SetPoint(2,pointx,m_rby);
break;
case 5:
SetPoint(2,pointx,pointy);
break;
case 6:
SetPoint(2,m_rbx,pointy);
break;
case 7:
SetPoint(1,pointx,m_lty);
SetPoint(2,m_rbx,pointy);
break;
case 8:
SetPoint(1,pointx,m_lty);
break;
case 9:
break;
}
//重新計算邊界矩形
CalcBounds(pView);
//修改文檔標志
m_pDocument->SetModifiedFlag();
}
// delta為邏輯坐標
void CRectObj::MoveTo(CPoint delta, CVisDrawView* pView)
{
ASSERT_VALID(this);
//把delta轉化為世界坐標
double pointx,pointy;
pointx = pView->ClientToWorld(delta.x);
pointy = -pView->ClientToWorld(delta.y);
//修改矩形兩頂點坐標
m_ltx = m_ltx + pointx;
m_lty = m_lty + pointy;
m_rbx = m_rbx + pointx;
m_rby = m_rby + pointy;
//重新計算邊界矩形
CalcBounds(pView);
//修改文檔標志
m_pDocument->SetModifiedFlag();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -