Как избежать пунктирных линий в GDI +?

На скриншотах, взятых из моего приложения MFC, показаны линии 2, которые должны быть параллельными.
2 пунктирные, параллельные линии 2 параллельные линии, одна сплошная, другая пунктирная

Линии нарисованы с использованием Gdiplus::Graphics::Drawline(),

Незначительная проблема в том, что пунктирные линии не прямые, а ломаные. Вы замечаете это, но это не имеет большого значения …

Реальная проблема заключается в том, что это не соответствует и линии, нарисованные с Gdiplus::DashStyleSolid действительно прямые.

Это ошибка в GDI +? Есть ли обходной путь?

Я попытался сделать минимальный пример, но я изо всех сил пытаюсь воспроизвести его …
Это может быть связано с очень большими значениями координат и небольшой разницей между их координатами.
Вот некоторые примерные координаты линии:

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)

Я заметил, что начальные точки идентичны, но это может быть вызвано округлением в выводе отладки …

Я мог бы воспроизвести это сейчас:
Пример приложения был сгенерирован как проект SDI, а класс представления наследует CScrollView (код и снимок экрана ниже).
Эффект «пунктирной линии» также, по-видимому, связан с толщиной пера. Линия проходит немного по-разному с изменяющейся толщиной, но я не нашел значения, которое все время приводит к параллельным линиям.

Винсент Порвик предлагает в комментарии, что это может быть результатом ошибок округления, так как 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.);
}

пересекающиеся линии

7

Решение

Я не думаю, что это связано с пунктирной и сплошной, но с точностью поплавка. Ваши координаты кажутся географическими. Обычно рекомендуется хранить все координаты как двойные, и когда вам нужно работать с библиотекой с меньшей точностью, сместите все координаты самостоятельно, прежде чем передавать их графическим функциям.

Правильный способ сделать это — выбрать опорную точку, близкую к точкам в вашем наборе данных (первая найденная вами координата в порядке), а затем вычесть ее координаты всем остальным точкам. Это сохраняет числовые значения около 0,0, то есть где поплавки имеют более высокую плотность разрешения.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]