📄 curvectrl.cpp
字号:
{
if (m_ArrCurve[iCurve]->m_bSelected)
nSelected++;
}
return nSelected;
}
//-------------------------------------------------------------------------------------------------
// 功能:图形放大显示
// 参数:point:mouse坐标
// v_iPage:一屏显示点数
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::CalcAllAdd(CPoint point,int v_iPage)
{
int v_iNum; //临时变量
float fHori,fVert; //临时变量
if(CalculateValue(point, fHori, fVert)) //计算鼠标按下的点在有效范围内?
{ //并换算成采样点的值(x、y)
if(fHori==0) //无效采样值
return;
v_iNum=int((fHori-m_fHoriBegin)/(m_fHoriEnd-m_fHoriBegin)*v_iPage-0.5);
//计算显示点在一屏中的位置
m_fHoriBegin=float(fHori-v_iNum); //X坐标显示起点
m_fHoriEnd=float(m_fHoriBegin+v_iPage); //X坐标显示终点
Invalidate(); //图形显示
}
}
//-------------------------------------------------------------------------------------------------
// 功能:
//-------------------------------------------------------------------------------------------------
// decription : calculate point in pixel by horizontal value and vertical value
// in parameter : fHori -- horizontal value
// fVert -- vertical value
// out parameter: point -- point in pixel, INVALID_POINT if out of drawing area
BOOL CCurveCtrl::CalculatePoint(float fHori, float fVert, CPoint& point)
{
point = INVALID_POINT;
float fHoriDiff = m_fHoriEnd - m_fHoriBegin;
float fHoriDlt = fHori - m_fHoriBegin;
if ( fHoriDlt < 0 || fHoriDiff <= 0 || (m_fHoriEnd - fHori) < 0)
return FALSE;
float fVertDiff = m_fVertMax - m_fVertMin;
float fVertDlt = fVert - m_fVertMin;
if ( fVertDlt < 0 || fVertDiff <= 0 )
return FALSE;
float fHoriCof = fHoriDlt / fHoriDiff;
float fVertCof = fVertDlt / fVertDiff;
point.x = m_RectCoord.left + int(m_RectCoord.Width() * fHoriCof + 0.5f);
point.y = m_RectCoord.bottom - int(m_RectCoord.Height() * fVertCof + 0.5f);
return TRUE;
}
// decription : calculate horizontal value and vertical value by point in pixel
// in parameter : point -- point in pixel
// out parameter: fHori -- horizontal value
// fVert -- vertical value
// return value : TRUE if success, and FALSE if point out of rect area in which drawing curve
BOOL CCurveCtrl::CalculateValue(const CPoint& point, float& fHori, float& fVert)
{
if (!m_ArrCurve.GetSize())
return FALSE;
// if point is out of drawing area
if (m_RectCoord.PtInRect(point))
{
float fHCof = float(point.x - m_RectCoord.left) / float(m_RectCoord.Width());
fHori = m_fHoriBegin + fHCof * (m_fHoriEnd - m_fHoriBegin);
float fVCof = float(point.y - m_RectCoord.top) / float(m_RectCoord.Height());
fVert = m_fVertMax - fVCof * (m_fVertMax - m_fVertMin);
return TRUE;
}
return FALSE;
}
void CCurveCtrl::ReCalcAllPoint()
{
for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
{
CCurve* pCurve = m_ArrCurve[iCurve];
ASSERT(pCurve->m_fArrHoriValue.GetSize() == pCurve->m_fArrVertValue.GetSize());
pCurve->m_ArrPoint.SetSize(pCurve->m_fArrHoriValue.GetSize());
for (int iPoint = 0; iPoint < pCurve->m_ArrPoint.GetSize(); iPoint++)
{
CalculatePoint(pCurve->m_fArrHoriValue[iPoint], pCurve->m_fArrVertValue[iPoint], pCurve->m_ArrPoint[iPoint]);
}
}
}
//-------------------------------------------------------------------------------------------------
// 功能:重新计算Y轴数据范围
// 参数:无
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::ReCalcAllVert()
{
int v_iEnd,v_iBegin; //临时变量
if (m_fHoriEnd<0) //显示曲线终止点小于0?
return;
m_fVertMax = -FLT_MAX / 2; //初始化最大值
m_fVertMin = FLT_MAX / 2; //初始化最小值
for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++) //曲线数量
{
v_iBegin=0; //曲线起始点
v_iEnd=0; //曲线终止点
CCurve* pCurve = m_ArrCurve[iCurve]; //曲线数据指针
v_iEnd=pCurve->m_fArrHoriValue.GetSize(); //曲线采集点数(???)
if(v_iEnd>m_fHoriEnd) //计算的曲线终止点 > 显示曲线终止点
v_iEnd=int(m_fHoriEnd); //计算的曲线终止点 = 显示曲线终止点
if(v_iBegin<m_fHoriBegin) //计算的曲线起始点 > 显示曲线终止点
v_iBegin=int(m_fHoriBegin); //计算的曲线起始点 = 显示曲线终止点
for (int iPoint = v_iBegin ; iPoint < v_iEnd ; iPoint++) //曲线显示范围计算
{
CalculateVertRange(pCurve->m_fArrVertValue[iPoint], TRUE); //最大值计算
CalculateVertRange(pCurve->m_fArrVertValue[iPoint], FALSE); //最小值计算
}
}
}
//-------------------------------------------------------------------------------------------------
// 功能:draw cross lines and output string of corresponding values
// 参数:无
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::DrawCross(CDC *pdc)
{
return;
CPoint point;
GetCursorPos(&point);
ScreenToClient(&point);
if(PtInRect(m_RectCoord, point))
{
// cross lines
if (/*!m_bEdit &&*/ m_bShowCross)
{
// color: using m_crAxis
CPen pentmp(PS_SOLID, 1, m_crAxis);
CPen *pOldPentmp=pdc->SelectObject(&pentmp);
pdc->MoveTo(point.x, m_RectCoord.top);
pdc->LineTo(point.x, m_RectCoord.bottom);
pdc->MoveTo(m_RectCoord.left, point.y);
pdc->LineTo(m_RectCoord.right, point.y);
pdc->SelectObject(pOldPentmp);
}
// out put string to top-right outside of the drawing rect
float fHori, fVert;
CString str;
CSize szText;
if (CalculateValue(point, fHori, fVert))
{
str.Format(_T("%.2f, %.4f"), int(10 * fHori) / 10.0f, fVert);
szText = pdc->GetTextExtent(str);
pdc->TextOut(m_RectCoord.right - szText.cx, m_RectCoord.top - szText.cy - 2, str);
}
}
}
// decription : disable base function to avoid flicker
BOOL CCurveCtrl::OnEraseBkgnd(CDC* /*pDC*/)
{
// return CWnd::OnEraseBkgnd(pDC);
return TRUE;
}
//-------------------------------------------------------------------------------------------------
// 功能:曲线移动(数据不变)
// 参数:bLeft:TRUE: move left; FALSE: move right
// nHoriGrid:移动点数
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::Move(BOOL bLeft,int nHoriGrid)
{
float fPerGird = float(nHoriGrid); //浮点转换
if (bLeft && (m_fHoriBegin + fPerGird < m_fHoriMax)) //左移:必须有绘制曲线的可见点
{
m_fHoriBegin += fPerGird; //起点
m_fHoriEnd += fPerGird; //终点
}
else if (!bLeft && (m_fHoriEnd - fPerGird > m_fHoriMin)) //右移:必须有绘制曲线的可见点
{
m_fHoriBegin -= fPerGird; //起点
m_fHoriEnd -= fPerGird; //终点
}
Invalidate(); //图形显示
}
//-------------------------------------------------------------------------------------------------
// 功能:曲线移动一页(数据不变)
// 参数:bLeft -- TRUE: move left; FALSE: move right
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::MovePage(BOOL bLeft)
{
float fPerPage = m_fHoriEnd - m_fHoriBegin; //移动点数
if (bLeft && (m_fHoriBegin + fPerPage < m_fHoriMax)) // move left
{
m_fHoriBegin += fPerPage; //起点
m_fHoriEnd += fPerPage; //终点
}
else if (!bLeft && (m_fHoriEnd - fPerPage > m_fHoriMin)) // move right
{
m_fHoriBegin -= fPerPage; //起点
m_fHoriEnd -= fPerPage; //终点
}
Invalidate();
}
//-------------------------------------------------------------------------------------------------
// 功能:曲线右移(增加曲线采集点数)
// 参数:pCurve -- curve object(曲线指针)
// fLen -- offset(增加数量)
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::CurveRight(CCurve* pCurve, float fLen)
{
if (pCurve == NULL) //无效曲线指针
return;
for (int iIndex = 0; iIndex < pCurve->m_ArrPoint.GetSize(); iIndex++)
{
pCurve->m_fArrHoriValue[iIndex] += fLen; //增加采集点数
// max value
m_fHoriMax = max(m_fHoriMax, pCurve->m_fArrHoriValue[iIndex]); //曲线最大点数
}
Restore(); //显示所有曲线
}
//-------------------------------------------------------------------------------------------------
// 功能:曲线左移(删除曲线采集点数)
// 参数:pCurve -- curve object(曲线指针)
// fLen -- offset(删除数量)
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::CurveLeft(CCurve* pCurve, float fLen)
{
if (pCurve == NULL) //无效曲线指针
return;
for (int iIndex = 0; iIndex < pCurve->m_ArrPoint.GetSize(); iIndex++)
{
pCurve->m_fArrHoriValue[iIndex] -= fLen; //删除采集点数
// min value
m_fHoriMin = min(m_fHoriMin, pCurve->m_fArrHoriValue[iIndex]); //曲线最小点数
}
Restore(); //显示所有曲线
}
//-------------------------------------------------------------------------------------------------
// 功能:显示所有曲线
// 参数:无
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::Restore()
{
float fVMin, fVMax; //临时变量
m_fHoriMin = FLT_MAX / 2; //X轴最小值
m_fHoriMax = -FLT_MAX / 2; //X轴最大值
m_fVertMin = fVMin = FLT_MAX / 2; //Y轴最小值
m_fVertMax = fVMax = -FLT_MAX / 2; //Y轴最大值
for (int iCur = 0; iCur < m_ArrCurve.GetSize(); iCur++) //计算最大值和最小值
{ //一条曲线
for (int iPt = 0; iPt < m_ArrCurve[iCur]->m_fArrHoriValue.GetSize(); iPt++)
{ //一点
m_fHoriMin = min(m_fHoriMin, m_ArrCurve[iCur]->m_fArrHoriValue[iPt]);
//X轴最小值
m_fHoriMax = max(m_fHoriMax, m_ArrCurve[iCur]->m_fArrHoriValue[iPt]);
//X轴最大值
fVMin = min(fVMin, m_ArrCurve[iCur]->m_fArrVertValue[iPt]); //Y轴最小值
fVMax = max(fVMax, m_ArrCurve[iCur]->m_fArrVertValue[iPt]); //Y轴最大值
}
}
m_fHoriBegin = m_fHoriMin; //屏幕显示起点
m_fHoriEnd = m_fHoriMax; //屏幕显示终点
// adjust
CalculateVertRange(fVMin, FALSE); //Y轴最小值处理(预留下边界)
CalculateVertRange(fVMax, TRUE); //Y轴最大值处理(预留上边界)
// restore zoom
m_iZoom = 0; //
Invalidate(); //绘制曲线
}
//-------------------------------------------------------------------------------------------------
// 功能:zoom in or out curves
// 参数:bIn -- TRUE: out; FALSE: in
//-------------------------------------------------------------------------------------------------
BOOL CCurveCtrl::Zoom(BOOL bIn)
{
bIn ? m_iZoom++ : m_iZoom--; //增加或
if (m_iZoom == 4)
{
m_iZoom--;
return FALSE;
}
else if (m_iZoom == -4)
{
m_iZoom++;
return FALSE;
}
float fDiff = (m_fHoriMax - m_fHoriMin) / 4.0f;
m_fHoriEnd = m_fHoriMax - m_iZoom * fDiff;
Invalidate();
return TRUE;
}
//-------------------------------------------------------------------------------------------------
// 功能:在X轴上镜像曲线
// 参数:无
//-------------------------------------------------------------------------------------------------
// description : mirror one curve in horizontal
// in parameter: pCurve -- curve object
// fMid -- center value
void CCurveCtrl::MirrorHori(CCurve* pCurve, float fMid)
{
if (!pCurve) //无效曲线指针
return;
for (int iIndex = 0; iIndex < pCurve->m_fArrHoriValue.GetSize(); iIndex++)
{ //曲线的每个点
pCurve->m_fArrHoriValue[iIndex] = 2 * fMid - pCurve->m_fArrHoriValue[iIndex];
} //
// resort
SortCurveData(pCurve); //
Restore(); //显示所有曲线
Invalidate(); //绘制曲线
}
//-------------------------------------------------------------------------------------------------
// 功能:显示所有曲线
// 参数:无
//-------------------------------------------------------------------------------------------------
// description : mirror one curve in vertical
// in parameter: pCurve -- curve object
// fMid -- center value
void CCurveCtrl::MirrorVert(CCurve* pCurve, float fMid)
{
if (!pCurve)
return;
for (int iIndex = 0; iIndex < pCurve->m_fArrVertValue.GetSize(); iIndex++)
{
pCurve->m_fArrVertValue[iIndex] = 2 * fMid - pCurve->m_fArrVertValue[iIndex];
}
// need not resort
Restore();
Invalidate();
}
//-------------------------------------------------------------------------------------------------
// 功能:计算用于显示的Y轴数据范围,调整其最大值和最小值确定绘制曲线的边界
// 参数:fValue -- Y轴数据
// bMax -- TRUE: 最大值; FALSE: 最小值
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::CalculateVertRange(float fValue, BOOL bMax)
{
CString str;
str.Format(_T("%.0f"), fabs(fValue));
// get integer digital count
int nEx = str.GetLength() - 1;
int ntemp = int(pow(10, nEx));
if (bMax && (fValue + ntemp * 0.002) > m_fVertMax)
{
m_fVertMax = fValue + 0.002f * ntemp;
}
else if (!bMax && (fValue - ntemp * 0.002) < m_fVertMin)
{
m_fVertMin = fValue - 0.002f * ntemp;
}
}
//-------------------------------------------------------------------------------------------------
// 功能:
// 参数:
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::SetHoriLabel(CString& str)
{
m_strHoriLabel = str;
}
//-------------------------------------------------------------------------------------------------
// 功能:
// 参数:
//-------------------------------------------------------------------------------------------------
CString CCurveCtrl::GetHoriLabel()
{
return m_strHoriLabel;
}
//-------------------------------------------------------------------------------------------------
// 功能:
// 参数:
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::SetVertLabel(CString& str)
{
m_strVertLabel = str;
}
//-------------------------------------------------------------------------------------------------
// 功能:
// 参数:
//-------------------------------------------------------------------------------------------------
CString CCurveCtrl::GetVertLabel()
{
return m_strVertLabel;
}
//-------------------------------------------------------------------------------------------------
// 功能:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -