在直线上画箭头的实现

前言

在练习用的画图工程上,原来画线是没有箭头的.
看见有个软件有画箭头的功能,要求加上.
自己先画了一下,没实现功能,挫~
逆向了那个软件的画箭头的实现,逆向出来,没怎么整理呢,功能已经不对了~
算法是对的,箭头已经画出来了,就是位置各种不对。
又不想从头再逆一回。
就调试了一下原始画箭头算法的实现,整理出来可用. 感觉比原始代码要精干:)
抄别人代码就是比自己直接写感觉要好,不会出现吭哧吭哧不出来的情况, 大部分工作是在整理代码.

效果

这里写图片描述

在直线一端画箭头的实现

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); ///< 画线时,受CPen影响
        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;

    // 分4个象限进行显示
    if ((x2 >= x1) && (y2 > y1)) {
        // 270 ~ 360度
        fArrowAngle = FPAI_DOT_5 + atan2(1.0, fOffsetX / fOffsetY);
    } else if ((x2 > x1) && (y2 <= y1)) {
        // 0 ~ 90度
        fArrowAngle = FPAI_DOT_5 - atan2(1.0, fOffsetX / fOffsetY);
    } else if ((x2 <= x1) && (y2 < y1)) {
        // 90 ~ 180度
        fArrowAngle = FPAI_1_DOT_5 + atan2(1.0, fOffsetX / fOffsetY);
    } else if ((x2 < x1) && (y2 >= y1)) {
        // 180 ~ 270度
        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));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值