免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4374 | 回复: 6
打印 上一主题 下一主题

画箭头,如何消除精度误差 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-01 13:12 |只看该作者 |倒序浏览
本帖最后由 xb_parasite 于 2011-06-01 13:17 编辑

最近遇到一个比较棘手的问题。
即在一个平面内画线段的箭头
我在网上找到了现成的方法。
参考:http://www.codeproject.com/KB/GDI/arrows.aspx
但是拿来用了之后,发现虽然能够画出来还样子可以,却总是有一些小小的误差,比如箭头偏左或者偏右了,线段不是确切的在箭头的中线上什么的。
应该是来源于计算过程中的误差。
大家一起看看,能不能有好点的方案减小或者消除误差,或者直接有另外的画箭头的方法可以很小误差的。

  1. #include "Arrow.h"
  2. #include <math.h>

  3. // ArrowTo()
  4. //
  5. void ArrowTo(HDC hDC, int x, int y, ARROWSTRUCT *pA) {

  6.         POINT ptTo = {x, y};

  7.         ArrowTo(hDC, &ptTo, pA);
  8. }

  9. double calculateLineLength(const POINT& pFrom,const POINT& pTo)
  10. {
  11.         double vecLine[2];
  12.         // build the line vector
  13.         vecLine[0] = (double) pTo.x - pFrom.x;
  14.         vecLine[1] = (double) pTo.y - pFrom.y;

  15.    // setup length parameters
  16.    double fLength = (double) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
  17.    return fLength ;
  18. }
  19. // ArrowTo()
  20. //
  21. void ArrowTo(HDC hDC, const POINT *lpTo, ARROWSTRUCT *pA) {

  22.         POINT pFrom;
  23.         POINT pBase;
  24.         POINT aptPoly[3];
  25.         double vecLine[2];
  26.         double vecLeft[2];
  27.         double fLength;
  28.         double th;
  29.         double ta;

  30.         // get from point
  31.         MoveToEx(hDC, 0, 0, &pFrom);

  32.         // set to point
  33.         aptPoly[0].x = lpTo->x;
  34.         aptPoly[0].y = lpTo->y;

  35.         // build the line vector
  36.         vecLine[0] = (double) aptPoly[0].x - pFrom.x;
  37.         vecLine[1] = (double) aptPoly[0].y - pFrom.y;

  38.         // build the arrow base vector - normal to the line
  39.         vecLeft[0] = -vecLine[1];
  40.         vecLeft[1] = vecLine[0];

  41.         // setup length parameters
  42.         fLength = (double) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
  43.         th = pA->nWidth / (2.0f * fLength);
  44.         ta = pA->nWidth / (2.0f * (tanf(pA->fTheta) / 2.0f) * fLength);

  45.    // find the base of the arrow
  46.    pBase.x = (int) (aptPoly[0].x + -ta * vecLine[0] +0.5);
  47.    pBase.y = (int) (aptPoly[0].y + -ta * vecLine[1]+0.5);

  48.    // build the points on the sides of the arrow
  49.    aptPoly[1].x = (int) (th * vecLeft[0]+0.5+pBase.x);
  50.    aptPoly[1].y = (int) (th * vecLeft[1]+0.5+pBase.y);
  51.    aptPoly[2].x = (int) (pBase.x + -th * vecLeft[0]+0.5);
  52.    aptPoly[2].y = (int) (pBase.y + -th * vecLeft[1]+0.5);
  53.    MoveToEx(hDC, pFrom.x, pFrom.y, NULL);

  54.         // draw we're fillin'...
  55.         if(pA->bFill) {
  56.       LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
  57.       Polygon(hDC, aptPoly, 3);
  58.    }

  59.    // ... or even jes chillin'...
  60.    else {
  61.       LineTo(hDC, pBase.x, pBase.y);
  62.                 LineTo(hDC, aptPoly[1].x, aptPoly[1].y);
  63.                 LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
  64.                 LineTo(hDC, aptPoly[2].x, aptPoly[2].y);
  65.                 LineTo(hDC, pBase.x, pBase.y);
  66.                 MoveToEx(hDC, aptPoly[0].x, aptPoly[0].y, NULL);
  67.         }
  68. }
复制代码

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2011-06-01 13:30 |只看该作者
这个不容易做的,要画得好需要平滑处理,不是只用一种颜色的。
你放大下MS Office中画的箭头就知道了

论坛徽章:
0
3 [报告]
发表于 2011-06-01 14:19 |只看该作者
回复 2# hellioncu
平滑处理是什么概念,能仔细解释一下吗?
跟颜色有什么关系?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2011-06-01 14:25 |只看该作者
回复  hellioncu
平滑处理是什么概念,能仔细解释一下吗?
跟颜色有什么关系?
xb_parasite 发表于 2011-06-01 14:19



    用不同的深度的颜色画,使得点阵导致的锯齿不明显

论坛徽章:
0
5 [报告]
发表于 2011-06-01 14:37 |只看该作者
箭头本身,三角形下边有时候倾斜,即跟线段不是垂直相交,这样的情况也是属于点阵导致的锯齿吗? 而不是计算过程中的误差吗

论坛徽章:
0
6 [报告]
发表于 2011-06-02 08:27 |只看该作者
箭头本身,三角形下边有时候倾斜,即跟线段不是垂直相交,这样的情况也是属于点阵导致的锯齿吗? 而不是计算过程中的误差吗

论坛徽章:
0
7 [报告]
发表于 2011-06-02 12:42 |只看该作者
再顶! 高手请关注!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP