如何避免在GDI +中破碎的虚线?
从我的MFC应用程序中截取的截图显示了应该平行的第2行。
线条使用Gdiplus::Graphics::Drawline()
绘制。
一个小问题是,虚线不是直线而是断开的。 你注意到它,但这不是什么大问题......
真正的问题是它不一致,用Gdiplus::DashStyleSolid
绘制的线条非常直。
这是GDI +中的错误吗? 有没有解决方法?
更新1
我试图做一个最小的例子,但我努力重现它......它可能与非常大的坐标值和它们的坐标之间的差异很小。 这些是一些示例行坐标:
Line 1: PointF(2.21866e+006, 1.40198e+006), PointF(2.21732e+006, 1.40111e+006)
Line 2: PointF(2.21866e+006, 1.40198e+006), PointF(2.21732e+006, 1.40112e+006)
我注意到开始点是相同的,但这可能是由调试输出中的四舍五入造成的。
更新2
我现在可以重现它:示例应用程序生成为SDI项目,视图类继承CScrollView(下面的代码和屏幕截图)。 “折线”效果也似乎与笔的厚度有关。 这条线与厚度变化有些不同,但我没有发现一直会产生平行线的值。
Vincent Porvik在评论中建议,这可能是舍入错误的结果,因为Gdiplus::REAL
被定义为float
。 我相信这种情况也是如此......
除了以某种方式使用较小的坐标值之外,我还有其他选择吗?
代码和屏幕截图
这些函数被添加/修改(除了GDI +初始化代码):
void CgdiplusLinesView::OnDraw(CDC* pDC)
{
CgdiplusLinesDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
pDC->SetBkMode(TRANSPARENT);
using namespace Gdiplus;
Graphics g(pDC->m_hDC);
g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
Pen solidPen(Color(0,0,0), 2.f);
Pen dashedPen(Color(0,0,0), 2.f);
dashedPen.SetDashStyle(DashStyleDash);
g.DrawLine(&dashedPen, PointF(4438749.500000, 2805806.500000), PointF(4434280.500000, 2802106.500000));
g.DrawLine(&solidPen, PointF(4438746.500000, 2805809.500000), PointF(4434277.500000, 2802109.500000));
}
void CgdiplusLinesView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
pDC->SetMapMode(MM_ISOTROPIC);
const int mapSizePixels = 8388608;
pDC->SetWindowExt(mapSizePixels, mapSizePixels);
pDC->SetViewportExt(mapSizePixels, mapSizePixels);
pDC->SetWindowOrg(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
//__super::OnPrepareDC(pDC, pInfo);
}
void CgdiplusLinesView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
SetScrollSizes(MM_TEXT, CSize(8388608, 8388608), CSize(1361, 1054));
SetScrollPos(SB_HORZ, 4434897.5);
SetScrollPos(SB_VERT, 2802645.);
}
我不认为这与虚线vs实线有关,但是具有浮点精度。 你的坐标似乎是地理坐标。 通常的良好做法是将所有坐标存储为双精度,并且当您需要使用较低精度的库时,在将所有坐标传递给图形函数之前自行偏移所有坐标。
正确的做法是选择一个靠近数据集中点的参考点(您发现的第一个坐标是可以的),然后将其坐标减去所有其他点。 这使得数值接近0.0,这是浮点数具有更高分辨率密度的地方。
链接地址: http://www.djcxy.com/p/11349.html