前言
如何绘制带箭头的直线,说来也简单,只需要算出箭头左右两边的坐标,再使用LineTo()函数即可。话不多说上代码。
代码
获得箭头坐标
已知直线的起点ptStar和终点ptEnd坐标,设定好箭头的夹角和需要的箭头长度,就可以调用下面的函数计算出箭头两边点的坐标。
//□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□//
//描述:获得箭头坐标
//参数:
// pStar 直线起始点
// pEnd 直线终点
// angle 箭头相对终点的夹角
// length 箭头长
// Arrowlf 输出箭头左边坐标
// ArrowRt 输出箭头右边坐标
//□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□//
void CArrowDraw::GetArrowPoint(CPoint pStar, CPoint pEnd, double angle, int length, POINT &Arrowlf, POINT &ArrowRt)
{
double theta;
double Px,Py;
double Px1 ,Py1 , Px2, Py2;
double len1, len2;
theta = angle / 180.0 * DRAW_PI; //角度转弧度
Px = pStar.x - pEnd.x;
Py = pStar.y - pEnd.y;
//向量P旋转theta角得到向量P1
Px1 = Px * cos(theta) - Py * sin(theta);
Py1 = Px * sin(theta) + Py * cos(theta);
//向量P旋转-theta角得到向量P2
Px2 = Px * cos(-theta) - Py * sin(-theta);
Py2 = Px * sin(-theta) + Py * cos(-theta);
//伸缩向量至指定长度
len1 = sqrt(Px1 * Px1 + Py1 * Py1);
Px1 = Px1 * length / len1;
Py1 = Py1 * length / len1;
len2 = sqrt(Px2 * Px2 + Py2 * Py2);
Px2 = Px2 * length / len2;
Py2 = Py2 * length / len2;
//平移变量至直线末端
Px1 = Px1 + pEnd.x;
Py1 = Py1 + pEnd.y;
Px2 = Px2 + pEnd.x;
Py2 = Py2 + pEnd.y;
Arrowlf.x = (int)Px1;
Arrowlf.y = (int)Py1;
ArrowRt.x = (int)Px2;
ArrowRt.y = (int)Py2;
}
此处提供2个应用场景:绘制实心箭头和直线+箭头
void CArrowDraw::DrawArrow(CDC *pDC)
{
CPoint ptArrow[4];
CPoint ptStar, ptEnd;
CPoint ptArrowLeft, ptArrowRight;
CPen penArrow;
CBrush brushArrow;
penArrow.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
brushArrow.CreateSolidBrush(RGB(255, 0, 0));
//绘制指北箭头
CPen *pOldPen = pDC->SelectObject(&penArrow);
ptStar.x = 10;
ptStar.y = 10;
ptEnd.x = 20;
ptEnd.y = 20;
//应用1: 只绘制箭头(实心箭头带颜色)
ptArrow[0].x = ptEnd.x;
ptArrow[0].y = ptEnd.y;
//获取箭头坐标
GetArrowPoint(pStar, ptArrow[0], 30, 10, ptArrow[1], ptArrow[2]);
ptArrow[3] = ptArrow[0];
CBrush *pOldBrush = pDC->SelectObject(&brushArrow);
pDC->Polygon(ptArrow, 4);
pDC->SelectObject(pOldBrush);
//应用2:直线+箭头
GetArrowPoint(ptStar, ptEnd, 30, 10, ptArrowLeft, ptArrowRight);
pDC->MoveTo(ptStar.x,ptStar.y);
pDC->LineTo(ptEnd.x,ptEnd.y);
pDC->MoveTo(ptEnd.x,ptEnd.y);
pDC->LineTo(ptArrowLeft.x, ptArrowLeft.y);
pDC->MoveTo(ptEnd.x,ptEnd.y);
pDC->LineTo(ptArrowRight.x, ptArrowRight.y);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
//释放资源
penArrow.DeleteObject();
brushArrow.DeleteObject();
}