7

私のMFCアプリケーションから取得したこれらのスクリーンショットは、平行である必要がある2行目を示しています。 2本の破線の平行線 2本の平行線、1本は実線、もう1本は破線

線は。を使用して描画され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

破線と実線の関係ではなく、浮動小数点の精度と関係があると思います。あなたの座標は地理座標のようです。通常の良い習慣は、すべての座標をdoubleとして保存することです。低精度のライブラリで作業する必要がある場合は、すべての座標を自分でオフセットしてから、グラフィック関数に渡します。

これを行う正しい方法は、データセット内のポイントに近い参照ポイントを選択し(最初に見つけた座標は問題ありません)、その座標を他のすべてのポイントに差し引くことです。これにより、数値が0.0近くに保たれ、フロートの解像度密度が高くなります。

于 2013-01-25T20:58:46.587 に答える