#include "StdAfx.h"
#include "Turtle.h"
#include "LogoView.h"
#include <math.h>
CTurtle::CTurtle(void)
{
m_bWorking = FALSE;
Retset();
}
CTurtle::~CTurtle(void)
{
}
void CTurtle::SetView(CLogoView *pView)
{
m_pView = pView;
}
// 修改画线状态
void CTurtle::SetDrawState(BOOL bDraw)
{
m_bDraw = bDraw;
}
// 修改是否显示海龟
void CTurtle::SetShowTurtleState(BOOL bShow)
{
m_bShow = bShow;
}
// 设置起点
void CTurtle::SetStartPoint(CPoint StartPoint)
{
m_StartPoint = StartPoint;
m_CurrentPoint = m_StartPoint;
m_Path.clear();
m_Path.push_back(m_StartPoint);
}
// 设置海龟命令
void CTurtle::SetCommand(CString strCMD)
{
m_StrCommand = strCMD;
m_index = 0;
m_CurIndex = 0;
}
// 海龟开始移动
void CTurtle::StartMove()
{
// while (HaveCMD())
// ResolveCMD();
if (!m_bWorking )
{
CreateThread(NULL,0,ThreadWork,this,0,NULL);
}
}
// 重置海龟
void CTurtle::Retset()
{
m_bDraw = TRUE;
m_bShow = TRUE;
m_StrCommand.Empty();
m_Angle = 0;
m_CurAngle = 0;
m_Length = 0;
m_CurLength = 0;
m_nRepeat = 0;
m_index = 0;
m_CurIndex = 0;
m_Path.clear();
m_Path.push_back(m_StartPoint);
m_CurrentPoint = m_StartPoint;
}
// 画海龟
void CTurtle::DrawTriangle(CDC* PDC, CPointF point, DWORD Color)
{
if (m_bShow)
{
CPen Pen(PS_SOLID,1,Color), *pOldPen;
pOldPen = PDC->SelectObject(&Pen);
PDC->MoveTo( point.x, max( 0, point.y - 3 ));
PDC->LineTo( max(0, point.x - 3), point.y + 3);
PDC->LineTo( point.x + 3, point.y + 3 );
PDC->LineTo( point.x, max( 0, point.y - 3 ) );
PDC->SelectObject(pOldPen);
}
}
// 画线
void CTurtle::DrawLine(CDC* PDC, DWORD Color)
{
if (0 == m_Path.size())
return;
CPen Pen(PS_SOLID,1,Color), *pOldPen;
pOldPen = PDC->SelectObject(&Pen);
CPointF Point = (*(m_Path.begin())).point;
PDC->MoveTo(CPoint((int)Point.x,(int)Point.y));
for (unsigned int i=1; i<m_Path.size(); i++)
{
if (m_Path[i-1].bEnd)
PDC->MoveTo(CPoint((int)m_Path[i].point.x,(int)m_Path[i].point.y));
else
{
PDC->LineTo(m_Path[i].point.x,m_Path[i].point.y);
PDC->MoveTo(CPoint((int)m_Path[i].point.x,(int)m_Path[i].point.y));
}
}
PDC->SelectObject(pOldPen);
}
// 是否还有命令
BOOL CTurtle::HaveCMD()
{
return (m_index < m_StrCommand.GetLength());
}
// 执行命令
void CTurtle::ExecuteCMD(CDC *pDC, CRect &rect)
{
CDC dcMem;
CBitmap bmp;
dcMem.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
dcMem.SelectObject(&bmp);
dcMem.FillSolidRect(rect,pDC->GetBkColor());
DrawLine(&dcMem,255);
if (m_Angle != m_CurAngle)
{
if (m_Angle/360 > 0)
m_Angle = m_Angle%360;
while (m_Angle < 0)
m_Angle += 360;
m_CurAngle = m_Angle;
DrawTriangle(&dcMem,m_CurrentPoint,255);
}
else if (m_Length != m_CurLength)
{
CPointF Point;
float len = m_Length;
m_CurLength = m_Length;
int iQuadrant = m_Angle/90;
int iAngle = m_Angle%90;
if (0 == iAngle)
{
if (iQuadrant == 0)
{
Point.x = m_CurrentPoint.x + len;
Point.y = m_CurrentPoint.y;
}
else if (iQuadrant == 1)
{
Point.x = m_CurrentPoint.x;
Point.y = m_CurrentPoint.y - len;
}
else if (iQuadrant == 2)
{
Point.x = m_CurrentPoint.x - len;
Point.y = m_CurrentPoint.y;
}
else if (iQuadrant == 3)
{
Point.x = m_CurrentPoint.x;
Point.y = m_CurrentPoint.y + len;
}
}
else
{
if (iQuadrant == 0)
{
Point.x = m_CurrentPoint.x + len*cos(((double)iAngle)*3.14/((double)180));
Point.y = m_CurrentPoint.y - len*sin(((double)iAngle)*3.14/((double)180));
}
else if (iQuadrant == 1)
{
Point.x = m_CurrentPoint.x - len*sin(((double)iAngle)*3.14/((double)180));
Point.y = m_CurrentPoint.y - len*cos(((double)iAngle)*3.14/((double)180));
}
else if (iQuadrant == 2)
{
Point.x = m_CurrentPoint.x - len*cos(((double)iAngle)*3.14/((double)180));
Point.y = m_CurrentPoint.y + len*sin(((double)iAngle)*3.14/((double)180));
}
else if (iQuadrant == 3)
{
Point.x = m_CurrentPoint.x + len*sin(((double)iAngle)*3.14/((double)180));
Point.y = m_CurrentPoint.y + len*cos(((double)iAngle)*3.14/((double)180));
}
}
if (m_bDraw)
{
dcMem.MoveTo(CPoint(m_CurrentPoint.x,m_CurrentPoint.y));
dcMem.LineTo(Point.x,Point.y);
}
if (m_Length == m_CurLength)
{
if (m_bDraw)
{
if (m_Path.size() > 0)
{
if (m_Path[m_Path.size()-1].bEnd)
{
if (abs(m_Path[m_Path.size()-1].point.x - m_CurrentPoint.x) > 0.000001 ||
abs(m_Path[m_Path.size()-1].point.y - m_CurrentPoint.y) > 0.000001)
m_Path.push_back(CPointInfo(m_CurrentPoint));
}
}
m_Path.push_back(Point);
}
else
{
if (m_Path.size() > 0)
m_Path[m_Path.size()-1].bEnd = TRUE;
}
m_CurrentPoint = Point;
m_CurLength = 0;
m_Length = 0;
}
else
{
m_CurLength = len;
}
DrawTriangle(&dcMem,Point,255);
}
else
{
DrawTriangle(&dcMem,m_CurrentPoint,255);
}
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC(); //删除DC
bmp.DeleteObject(); //删除位图
m_pView->Invalidate(FALSE);
}
void CTurtle::ResolveCMD(CString strCMD)
{
int Repeat = 0;
int index = 0;
while (index < strCMD.GetLength())
{
Repeat = 0;
if (' ' == strCMD.GetAt(index))
{
index++;
continue;
}
CString strTemp;
CString strKey;
strKey = strCMD.Mid(index,4);
if (0 == strKey.Compare(_T("前进")))
{
index += 4;
while (strCMD.GetAt(index) < '0'|| strCMD.GetAt(m_CurIndex)>'9')
index++;
strTemp = strCMD.Right(strCMD.GetLength() - index);
CAction ac;
ac.type = Front;
ac.value = atof(strTemp);
m_ListAction.push_back(ac);
while (index < strCMD.GetLength() && strCMD.GetAt(index) != ' ')
index++;
}
else if (0 == strKey.Compare(_T("后退")))
{
index += 4;
while (strCMD.GetAt(index) < '0'|| strCMD.GetAt(m_CurIndex)>'9')
index++;
strTemp = strCMD.Right(strCMD.GetLength() - index);
CAction ac;
ac.type = Back;
ac.value = -atof(strTemp);
m_ListAction.push_back(ac);
while (index < strCMD.GetLength() && strCMD.GetAt(index) != ' ')
index++;
}
else if (0 == strKey.Compare(_T("左转")))
{
index += 4;
while (strCMD.GetAt(index) < '0'|| strCMD.GetAt(m_CurIndex)>'9')
index++;
strTemp = strCMD.Right(strCMD.GetLength() - index);
CAction ac;
ac.type = Left;
ac.value = atoi(strTemp);
m_ListAction.push_back(ac);
while (index < strCMD.GetLength() && strCMD.GetAt(index) != ' ')
index++;
}
else if (0 == strKey.Compare(_T("右转")))
{
index += 4;
while (strCMD.GetAt(index) < '0'|| strCMD.GetAt(m_CurIndex)>'9')
index++;
strTemp = strCMD.Right(strCMD.GetLength() - index);
CAction ac;
ac.type = Right;
ac.value = -atoi(strTemp);
m_ListAction.push_back(ac);
while (index < strCMD.GetLength() && strCMD.GetAt(index) != ' ')
index++;
}
else if (0 == strKey.Compare(_T("抬起")))
{
CAction ac;
ac.type = Up;
ac.value = 0;
m_ListAction.push_back(ac);
index += 4;
}
else if (0 == strKey.Compare(_T("放下")))
{
CAction ac;
ac.type = Down;
ac.value = 0;
m_ListAction.push_back(ac);
index += 4;
}
else if (0 == strKey.Compare(_T("隐藏")))
{
CAction ac;
ac.type = Hide;
ac.value = 0;
m_ListAction.push_back(ac);
index += 4;
}
else if (0 == strKey.Compare(_T("显示")))
{
CAction ac;
ac.type = Show;
ac.value = 0;
m_ListAction.push_back(ac);
index += 4;
}
else if (0 == strKey.Compare(_T("重复")))
{
index += 4;
while (strCMD.GetAt(index) < '0'|| strCMD.GetAt(m_CurIndex)>'9')
index++;
strTemp = strCMD.Right(s