📄 draw.cpp
字号:
double cx, cy;
a = abs(m_x1 - m_x2) * 0.5;//椭圆X轴长度
b = abs(m_y1 - m_y2) * 0.5;//椭圆Y轴长度
cx = (m_x1 + m_x2) * 0.5;//椭圆中心点X坐标
cy = (m_y1 + m_y2) * 0.5;//椭圆中心点Y坐标
if(a > b)
{//椭圆长轴为X轴
c = sqrt(a*a - b*b);
fx1 = cx - c;
fx2 = cx + c;
fy1 = fy2 = cy;
}
else
{
c = sqrt(b*b - a*a);
fx1 = fx2 = cx;
fy1 = cy - c;
fy2 = cy + c;
a = b;
}
b = sqrt((fx1 - x)*(fx1 - x) + (fy1 - y)*(fy1 - y));//指定点到第一焦点的距离
b += sqrt((fx2 - x)*(fx2 - x) + (fy2 - y)*(fy2 - y));//指定点到第二焦点的距离
a = fabs(2*a - b);//指定点到两焦点的距离和
return(a < MAXOFFSET);
}
//-----------------------------------
// 以下为CDrawCircle(绘圆)类方法实现
//-----------------------------------
IMPLEMENT_SERIAL(CDrawCircle, CDrawObject, 1);
void CDrawCircle::Serialize(CArchive& ar)
{
COLORREF color;
if(ar.IsLoading())
{
ar >> m_nStyle >> color >> m_x >> m_y >> m_r;
SetPenColor(color);
}
else
{
color = GetPenColor();
ar << m_nStyle << color << m_x << m_y << m_r;
}
}
CDrawCircle::CDrawCircle(COLORREF color)
{
m_x=m_y=m_r=0;
SetPenColor(color);
m_nStyle = IDT_CIRCLE;
}
void CDrawCircle::Draw(CDC* pDC)
{
if(!this)
{//当前类为空,既无效类指针
return;
}
COLORREF CopyColor = GetPenColor();
CPen pen(PS_SOLID, 1, CopyColor);
int oldmode = pDC->GetROP2();
CPen* oldpen = pDC->SelectObject(&pen);//指定绘制笔;
//设置为“空”刷,既不填充。
CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);;
pDC->SetROP2(R2_COPYPEN);//指定绘制模式
pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆
//恢复DC
pDC->SetROP2(oldmode);
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
pen.DeleteObject();//释放笔资源
}
int CDrawCircle::NewPoint(long x, long y)
{
m_x = x;
m_y = y;
return 4;
}
int CDrawCircle::SelectAt(long x, long y)
{
if(AtPoint(m_x-m_r, m_y, x, y))
{//指针靠近左点
return 1;
}
else if(AtPoint(m_x, m_y-m_r, x, y))
{//指针靠近上点
return 2;
}
else if(AtPoint(m_x+m_r, m_y, x, y))
{//指针靠近右点
return 3;
}
else if(AtPoint(m_x, m_y+m_r, x, y))
{//指针靠近右下角点
return 4;
}
else if(AtPoint(m_x, m_y, x, y))
{
return 5;
}
else if(AtCurve(x, y))
{//指针在圆上
m_oldx = x;
m_oldy = y;
return 6;
}
else
return 0;
}
void CDrawCircle::MoveAt(CDC *pDC, int flags, long x, long y)
{
//以下设置DC
COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
CPen pen(PS_SOLID, 1, XorColor);
int oldmode = pDC->GetROP2();
CPen* oldpen = pDC->SelectObject(&pen);
//设置为“空”刷,既不填充。
CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pDC->SetROP2(R2_XORPEN);
if(m_bSelected)
{//以前已经选择了,取消热点
HotPoints(pDC);
}
//删除原图形
pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆
//修改新图形坐标
switch(flags)
{
case 1:
case 2:
case 3:
case 4:
m_r = (long)sqrt((m_x-x)*(m_x-x) + (m_y-y)*(m_y-y));
break;
case 5:
m_x = x;
m_y = y;
break;
case 6:
m_x += x-m_oldx;
m_y += y-m_oldy;
m_oldx = x;
m_oldy = y;
break;
}
//绘新图形
pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆
if(m_bSelected)
{//以前已经选择了,设置热点
HotPoints(pDC);
}
//以下恢复DC
pDC->SetROP2(oldmode);
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
pen.DeleteObject();
}
void CDrawCircle::HotPoints(CDC* pDC)
{
HotPoint(pDC, m_x-m_r, m_y);// 1
HotPoint(pDC, m_x, m_y-m_r);// 2
HotPoint(pDC, m_x+m_r, m_y);// 3
HotPoint(pDC, m_x, m_y+m_r);// 4
HotPoint(pDC, m_x, m_y);// 圆心
}
void CDrawCircle::Selected(CDC *pDC, bool select)
{
if(!this)
{//如果类指针无效,直接返回
return;
}
if(select)
{
if(!m_bSelected)
{//以前未选择,绘热点并设置选择标志
HotPoints(pDC);
m_bSelected = true;
}
}
else
{
if(m_bSelected)
{//以前已经选择了,取消热点设置并清选择标志
HotPoints(pDC);
m_bSelected = false;
}
}
}
bool CDrawCircle::AtCurve(long x, long y)
{
double l;
l = fabs(sqrt((m_x - x)*(m_x - x) + (m_y - y)*(m_y - y)) - m_r);
return(l < MAXOFFSET);
}
//-----------------------------------
// 以下为CDrawPLine(绘折线)类方法实现
//-----------------------------------
IMPLEMENT_SERIAL(CDrawPLine, CDrawObject, 1);
void CDrawPLine::Serialize(CArchive& ar)
{
COLORREF color;
int i;
if(ar.IsLoading())
{
ar >> m_nStyle >> color >> m_nNumber;
SetPenColor(color);
for(i=0;i<m_nNumber;i++)
{
ar >> m_aPoints[i].x >> m_aPoints[i].y;
}
}
else
{
color = GetPenColor();
ar << m_nStyle << color << m_nNumber;
for(i=0;i<m_nNumber;i++)
{
ar << m_aPoints[i].x << m_aPoints[i].y;
}
}
}
CDrawPLine::CDrawPLine(COLORREF color)
{
m_nNumber = 0;
SetPenColor(color);
m_nStyle = IDT_PLINE;
}
void CDrawPLine::Draw(CDC* pDC)
{
if(!this)
{//当前类为空,既无效类指针
return;
}
COLORREF CopyColor = GetPenColor();
CPen pen(PS_SOLID, 1, CopyColor);
int oldmode = pDC->GetROP2();
CPen* oldpen = pDC->SelectObject(&pen);//指定绘制笔;
pDC->SetROP2(R2_COPYPEN);//指定绘制模式
int i;
pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
for(i=1; i<m_nNumber; i++)
{
pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);//绘折线
}
//恢复DC
pDC->SetROP2(oldmode);
pDC->SelectObject(oldpen);
pen.DeleteObject();//释放笔资源
}
int CDrawPLine::NewPoint(long x, long y)
{
m_nNumber = 1;
m_aPoints[0].x = x;
m_aPoints[0].y = y;
m_oldx = x;
m_oldy = y;
return 2;
}
int CDrawPLine::AddPoint(long x, long y)
{
if(m_nNumber < MAXPLINEPOINT)
{
m_aPoints[m_nNumber].x = x;
m_aPoints[m_nNumber].y = y;
m_nNumber++;
}
//判断是否可继续绘折线
if(m_nNumber != MAXPLINEPOINT)
{//可继续下一点
return m_nNumber+1;
}
else
return 0;
}
int CDrawPLine::SelectAt(long x, long y)
{
int i;
if(AtPoint(m_aPoints[0].x, m_aPoints[0].y, x, y))
{//检查是否选择第一点
return 1;
}
for(i=1;i<m_nNumber; i++)
{
if(AtPoint(m_aPoints[i].x, m_aPoints[i].y, x, y))
{
return i+1;
}
if(AtLine(m_aPoints[i-1].x, m_aPoints[i-1].y, m_aPoints[i].x, m_aPoints[i].y, x, y))
{
m_oldx = x;
m_oldy = y;
return -1;//指针在直线上
}
}
return 0;
}
void CDrawPLine::MoveAt(CDC *pDC, int flags, long x, long y)
{
//以下设置DC
COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
CPen pen(PS_SOLID, 1, XorColor);
int i;
int oldmode = pDC->GetROP2();
CPen* oldpen = pDC->SelectObject(&pen);
//设置为“空”刷,既不填充。
CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pDC->SetROP2(R2_XORPEN);
if(m_bSelected)
{//以前已经选择了,取消热点
HotPoints(pDC);
}
//修改新图形坐标
if(flags == 1)
{//移动折线第一端点
pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
pDC->LineTo(m_aPoints[1].x, m_aPoints[1].y);
m_aPoints[0].x = x;
m_aPoints[0].y = y;
pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
pDC->LineTo(m_aPoints[1].x, m_aPoints[1].y);
}
else if(flags == m_nNumber)
{//移动折线最后端点
pDC->MoveTo(m_aPoints[m_nNumber-2].x, m_aPoints[m_nNumber-2].y);
pDC->LineTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
m_aPoints[m_nNumber-1].x = x;
m_aPoints[m_nNumber-1].y = y;
pDC->MoveTo(m_aPoints[m_nNumber-2].x, m_aPoints[m_nNumber-2].y);
pDC->LineTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
}
else if(flags == m_nNumber +1)
{//移动点超出范围,只有增加端点时出现
pDC->MoveTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
pDC->LineTo(m_oldx, m_oldy);
m_oldx = x;
m_oldy = y;
pDC->MoveTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
pDC->LineTo(m_oldx, m_oldy);
}
else if(flags > 1 && flags < m_nNumber)
{//移动折线中间端点
pDC->MoveTo(m_aPoints[flags-2].x, m_aPoints[flags-2].y);
pDC->LineTo(m_aPoints[flags-1].x, m_aPoints[flags-1].y);
pDC->LineTo(m_aPoints[flags].x, m_aPoints[flags].y);
m_aPoints[flags-1].x = x;
m_aPoints[flags-1].y = y;
pDC->MoveTo(m_aPoints[flags-2].x, m_aPoints[flags-2].y);
pDC->LineTo(m_aPoints[flags-1].x, m_aPoints[flags-1].y);
pDC->LineTo(m_aPoints[flags].x, m_aPoints[flags].y);
}
else if(flags == -1)
{//移动整个折线
pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
m_aPoints[0].x += x-m_oldx;
m_aPoints[0].y += y-m_oldy;
for(i=1;i<m_nNumber;i++)
{
pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);//删折线
m_aPoints[i].x += x-m_oldx;
m_aPoints[i].y += y-m_oldy;
}
pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
for(i=1; i<m_nNumber; i++)
{//绘折线
pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);
}
m_oldx = x;
m_oldy = y;
}
if(m_bSelected)
{//以前已经选择了,设置热点
HotPoints(pDC);
}
//以下恢复DC
pDC->SetROP2(oldmode);
pDC->SelectObject(oldpen);
pDC->SelectObject(oldbrush);
pen.DeleteObject();
}
void CDrawPLine::HotPoints(CDC* pDC)
{
int i;
for(i=0; i<m_nNumber; i++)
{
HotPoint(pDC, m_aPoints[i].x, m_aPoints[i].y);
}
}
void CDrawPLine::Selected(CDC *pDC, bool select)
{
if(!this)
{//如果类指针无效,直接返回
return;
}
if(select)
{
if(!m_bSelected)
{//以前未选择,绘热点并设置选择标志
HotPoints(pDC);
m_bSelected = true;
}
}
else
{
if(m_bSelected)
{//以前已经选择了,取消热点设置并清选择标志
HotPoints(pDC);
m_bSelected = false;
}
}
}
//-----------------------------------
// 以下为CDrawFont(绘标记)类方法实现
//-----------------------------------
IMPLEMENT_SERIAL(CDrawFont, CDrawObject, 1);
void CDrawFont::Serialize(CArchive& ar)
{
COLORREF color;
if(ar.IsLoading())
{
ar >> m_nStyle >> color >> m_x >> m_y;
SetPenColor(color);
}
else
{
color = GetPenColor();
ar << m_nStyle << color << m_x << m_y;
}
}
CDrawFont::CDrawFont(COLORREF color)
{
m_x=m_y=0;
SetPenColor(color);
m_nStyle = IDT_FONT;
}
void CDrawFont::Draw(CDC* pDC)
{
if(!this)
{//当前类为空,既无效类指针
return;
}
COLORREF CopyColor = GetPenColor();
CPen pen(PS_SOLID, 1, CopyColor), *oldpen;
int oldmode = pDC->GetROP2();
oldpen = pDC->SelectObject(&pen);//指定绘制笔
pDC->SetROP2(R2_COPYPEN);//指定绘制模式
DrawFont(pDC);
pDC->SelectObject(oldpen);//恢复DC
pDC->SetROP2(oldmode);
pen.DeleteObject();//释放笔资源
}
int CDrawFont::NewPoint(long x, long y)
{
m_x = x;
m_y = y;
return 1;
}
int CDrawFont::SelectAt(long x, long y)
{
if(AtPoint(m_x, m_y, x, y))
{//指针靠近端点
return 1;
}
else
{
return 0;
}
}
void CDrawFont::MoveAt(CDC *pDC, int flags, long x, long y)
{
//以下设置DC
COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
CPen pen(PS_SOLID, 1, XorColor), *oldpen;
int oldmode = pDC->GetROP2();
oldpen = pDC->SelectObject(&pen);
pDC->SetROP2(R2_XORPEN);
if(m_bSelected)
{//以前已经选择了,取消热点
HotPoints(pDC);
}
//删除原标记
DrawFont(pDC);
//修改新图形坐标
if(flags == 1)
{//移动左上角
m_x = x, m_y = y;
}
//绘新图形
DrawFont(pDC);
if(m_bSelected)
{//以前已经选择了,设置热点
HotPoints(pDC);
}
//以下恢复DC
pDC->SetROP2(oldmode);
pDC->SelectObject(oldpen);
pen.DeleteObject();//释放笔资源
}
void CDrawFont::HotPoints(CDC* pDC)
{
HotPoint(pDC, m_x, m_y);// 端点
}
void CDrawFont::Selected(CDC *pDC, bool select)
{
if(!this)
{//如果类指针无效,直接返回
return;
}
if(select)
{
if(!m_bSelected)
{//以前未选择,绘热点并设置选择标志
HotPoints(pDC);
m_bSelected = true;
}
}
else
{
if(m_bSelected)
{//以前已经选择了,取消热点设置并清选择标志
HotPoints(pDC);
m_bSelected = false;
}
}
}
void CDrawFont::DrawFont(CDC* pDC)
{
int fontsize = 6;
int dsize = fontsize * 0.7 + 0.5;
pDC->MoveTo(m_x-fontsize, m_y);
pDC->LineTo(m_x+fontsize+1, m_y);
pDC->MoveTo(m_x, m_y-fontsize);
pDC->LineTo(m_x, m_y+fontsize+1);
pDC->MoveTo(m_x-dsize, m_y-dsize);
pDC->LineTo(m_x+dsize+1, m_y+dsize+1);
pDC->MoveTo(m_x-dsize, m_y+dsize);
pDC->LineTo(m_x+dsize+1, m_y-dsize-1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -