前言
在练习用的画图工程上,原来画线是没有箭头的.
看见有个软件有画箭头的功能,要求加上.
自己先画了一下,没实现功能,挫~
逆向了那个软件的画箭头的实现,逆向出来,没怎么整理呢,功能已经不对了~
算法是对的,箭头已经画出来了,就是位置各种不对。
又不想从头再逆一回。
就调试了一下原始画箭头算法的实现,整理出来可用. 感觉比原始代码要精干:)
抄别人代码就是比自己直接写感觉要好,不会出现吭哧吭哧不出来的情况, 大部分工作是在整理代码.
效果
在直线一端画箭头的实现
void CShapeLine::OnDraw(CDC* pDC) {
CPen* pPenOrg = NULL;
if (NULL == pDC) {
return;
}
if (m_bValidPtBegin) {
CPen pen(GetShapeParam()->m_nPenStyle,
GetShapeParam()->m_nWidth,
GetShapeParam()->m_crColorPen);
pPenOrg = pDC->SelectObject(&pen);
pDC->MoveTo(m_ptBegin);
pDC->LineTo(m_bValidPtEnd ? m_ptEnd : m_ptLast);
DrawArrow(pDC);
if (GetShapeParam()->m_bWasSelect) {
OnDrawWasSelect(pDC);
}
pDC->SelectObject(pPenOrg);
}
}
void CShapeLine::DrawArrow(CDC* pDC) {
const double FPAI = 3.141592653589793238462643383249901429;
const double FPAI_DOT_5 = FPAI*0.5;
const double FPAI_1_DOT_5 = FPAI*1.5;
CPoint ptBegin = m_ptBegin;
CPoint ptEnd = m_bValidPtEnd ? m_ptEnd : m_ptLast;
int x1 = ptBegin.x;
int y1 = ptBegin.y;
int x2 = ptEnd.x;
int y2 = ptEnd.y;
double fArrowAngle = 0;
double fLineLengthNew = (float)fabs(GetLineLength(x1, y1, x2, y2) + 0.5);
double fOffsetY = fabs(y2 - y1);
double fOffsetX = fabs(x2 - x1);
double fSin = 0;
double fCos = 0;
int PtArrowBeginX = 0;
int PtArrowBeginY = 0;
if ((x2 >= x1) && (y2 > y1)) {
fArrowAngle = FPAI_DOT_5 + atan2(1.0, fOffsetX / fOffsetY);
} else if ((x2 > x1) && (y2 <= y1)) {
fArrowAngle = FPAI_DOT_5 - atan2(1.0, fOffsetX / fOffsetY);
} else if ((x2 <= x1) && (y2 < y1)) {
fArrowAngle = FPAI_1_DOT_5 + atan2(1.0, fOffsetX / fOffsetY);
} else if ((x2 < x1) && (y2 >= y1)) {
fArrowAngle = FPAI_1_DOT_5 - atan2(1.0, fOffsetX / fOffsetY);
}
fSin = sin(fArrowAngle);
fCos = cos(fArrowAngle);
PtArrowBeginX = x1 + (int)(fSin * fLineLengthNew);
PtArrowBeginY = (int)fabs(fCos * fLineLengthNew - y1);
pDC->MoveTo(
x1 + (int)(fSin * (fLineLengthNew - 10) - fCos * 10.0),
(int)fabs(fCos * (fLineLengthNew - 10) - fSin * -10.0 - y1));
pDC->LineTo(PtArrowBeginX, PtArrowBeginY);
pDC->MoveTo(
x1 + (int)(fSin * (fLineLengthNew - 10) + fCos * 10.0),
(int)fabs(fCos * (fLineLengthNew - 10) - fSin * 10.0 - y1));
pDC->LineTo(PtArrowBeginX, PtArrowBeginY);
}
double CShapeLine::GetLineLength(int x1, int y1, int x2, int y2)
{
return sqrt(pow((double)(x1 - x2), 2.0) + pow((double)(y1 - y2), 2.0));
}