7

这些屏幕截图取自我的 MFC 应用程序,显示了应该平行的第 2 行。 2 条虚线平行线 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.);
}

交叉线

4

1 回答 1

3

I don't think it has to do with dashed vs solid, but with float precision. Your coordinates seem to be geographic coordinates. The usual good practice has been to store all coordinates as doubles, and when you need to work with a lower precision library, offset all coordinates yourself before passing them to the graphics functions.

The correct way to do that is to choose a reference point that is close to the points in your dataset (first coordinate you find is ok) and then substract its coordinates to all other points. This keeps the numerical values near 0.0 that is where floats have higher resolution density.

于 2013-01-25T20:58:46.587 回答