- 论坛徽章:
- 0
|
本帖最后由 xb_parasite 于 2011-06-01 13:17 编辑
最近遇到一个比较棘手的问题。
即在一个平面内画线段的箭头
我在网上找到了现成的方法。
参考:http://www.codeproject.com/KB/GDI/arrows.aspx
但是拿来用了之后,发现虽然能够画出来还样子可以,却总是有一些小小的误差,比如箭头偏左或者偏右了,线段不是确切的在箭头的中线上什么的。
应该是来源于计算过程中的误差。
大家一起看看,能不能有好点的方案减小或者消除误差,或者直接有另外的画箭头的方法可以很小误差的。
- #include "Arrow.h"
- #include <math.h>
- // ArrowTo()
- //
- void ArrowTo(HDC hDC, int x, int y, ARROWSTRUCT *pA) {
- POINT ptTo = {x, y};
- ArrowTo(hDC, &ptTo, pA);
- }
- double calculateLineLength(const POINT& pFrom,const POINT& pTo)
- {
- double vecLine[2];
- // build the line vector
- vecLine[0] = (double) pTo.x - pFrom.x;
- vecLine[1] = (double) pTo.y - pFrom.y;
- // setup length parameters
- double fLength = (double) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
- return fLength ;
- }
- // ArrowTo()
- //
- void ArrowTo(HDC hDC, const POINT *lpTo, ARROWSTRUCT *pA) {
- POINT pFrom;
- POINT pBase;
- POINT aptPoly[3];
- double vecLine[2];
- double vecLeft[2];
- double fLength;
- double th;
- double ta;
- // get from point
- MoveToEx(hDC, 0, 0, &pFrom);
- // set to point
- aptPoly[0].x = lpTo->x;
- aptPoly[0].y = lpTo->y;
- // build the line vector
- vecLine[0] = (double) aptPoly[0].x - pFrom.x;
- vecLine[1] = (double) aptPoly[0].y - pFrom.y;
- // build the arrow base vector - normal to the line
- vecLeft[0] = -vecLine[1];
- vecLeft[1] = vecLine[0];
- // setup length parameters
- fLength = (double) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
- th = pA->nWidth / (2.0f * fLength);
- ta = pA->nWidth / (2.0f * (tanf(pA->fTheta) / 2.0f) * fLength);
- // find the base of the arrow
- pBase.x = (int) (aptPoly[0].x + -ta * vecLine[0] +0.5);
- pBase.y = (int) (aptPoly[0].y + -ta * vecLine[1]+0.5);
- // build the points on the sides of the arrow
- aptPoly[1].x = (int) (th * vecLeft[0]+0.5+pBase.x);
- aptPoly[1].y = (int) (th * vecLeft[1]+0.5+pBase.y);
- aptPoly[2].x = (int) (pBase.x + -th * vecLeft[0]+0.5);
- aptPoly[2].y = (int) (pBase.y + -th * vecLeft[1]+0.5);
- MoveToEx(hDC, pFrom.x, pFrom.y, NULL);
- // draw we're fillin'...
- if(pA->bFill) {
- LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
- Polygon(hDC, aptPoly, 3);
- }
- // ... or even jes chillin'...
- else {
- LineTo(hDC, pBase.x, pBase.y);
- LineTo(hDC, aptPoly[1].x, aptPoly[1].y);
- LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
- LineTo(hDC, aptPoly[2].x, aptPoly[2].y);
- LineTo(hDC, pBase.x, pBase.y);
- MoveToEx(hDC, aptPoly[0].x, aptPoly[0].y, NULL);
- }
- }
复制代码 |
|