Как я могу отобразить квадратное растровое изображение в произвольный четырехсторонний многоугольник, используя GDI? - PullRequest
15 голосов
/ 08 марта 2012

Мне нужно нарисовать квадратное изображение, сопоставленное или преобразованное в неизвестный во время компиляции четырехсторонний многоугольник.Как я могу это сделать?

Более подробное объяснение

Конкретная проблема - рендеринг фрагмента карты с непрямоугольной проекцией карты.Предположим, у меня есть следующий тайл:

Square tile

, и я знаю, что здесь должны быть четыре угловые точки:

Four distorted corners

Даночто я хотел бы получить следующий вывод:

Distorted, image-mapped polygon

Квадратный тайл может быть:

  • Поворот;и / или
  • быть более узким на одном конце, чем на другом.

I думаю второй элемент означает, что для этого требуется неаффинное преобразование.

Случайные дополнительные заметки

Четырехсторонний? Возможно, чтобы быть полностью правильным, плитка должна отображаться в многоугольник с помощьюболее четырех точек, но для наших целей и в масштабах, которых оно нарисовано, должно быть достаточно квадрата -> другого преобразования четырехугольного многоугольника.

Почему предпочтительно только GDI? Всерендеринг до сих пор выполняется с использованием GDI, и я хочу, чтобы код (а) был быстрым и (б) требовал как можно меньше дополнительных библиотек.Мне известно о некоторой поддержке преобразований в GDI , и я экспериментировал с ними сегодня, но даже после экспериментов с ними я не уверен, достаточно ли они гибки для этой цели.Если это так, мне не удалось это выяснить, и поэтому я был бы очень признателен за пример кода.

GDI + также подходит, поскольку мы используем его где-то еще, но я знаю, что он может быть медленным, издесь важна скорость.

Еще одна альтернатива - это что угодно Delphi - / C ++ Builder -specific;эта программа написана в основном на C ++ с использованием VCL, и соответствующая графика в настоящее время отрисовывается в TCanvas со смесью методов TCanvas и необработанных вызовов WinAPI / GDI.

Наложение изображений: Одно последнее замечание: один цвет в плитке может быть для прозрачности цветовых клавиш: то есть все белые (скажем) квадраты в вышеупомянутой плитке должны быть прозрачными при рисовании поверх того, что находится под ними.В настоящее время плитки рисуются для прямоугольных или выровненных по оси прямоугольных целей с помощью TransparentBlt .

Я прошу прощения за все дополнительные предостережения, которые усложняют этот вопрос, чем «какой алгоритм мне использовать?Но я с радостью приму ответы только с алгоритмической информацией.

Ответы [ 3 ]

6 голосов
/ 08 марта 2012

Взгляните на 3D Lab Векторная графика .(Специально «Футбольное поле» в демоверсии).


Еще один крутой ресурс - AggPas с полным исходным кодом ( загрузка )

AggPas - это открытый исходный код и бесплатная библиотека векторной графики 2D.Это собственный порт Object Pascal библиотеки Anti-Grain Geometry - AGG, изначально написанный Максимом Шеманаревым на C ++.AggPas не зависит от какого-либо графического API или технологии.По сути, вы можете думать об AggPas как о механизме рендеринга, который создает пиксельные изображения в памяти из некоторых векторных данных.

Вот как выглядит демоверсия perspective:

enter image description here

После преобразования:

enter image description here

6 голосов
/ 08 марта 2012

Возможно, вы также захотите взглянуть на Graphics32 . На приведенном ниже снимке экрана показано, как выглядит демоверсия в GR32

5 голосов
/ 08 марта 2012

Общая методика описана в «Цифровом искажении» Джорджа Вольберга.Похоже, этот реферат содержит соответствующую математику, как и этот документ .Вам нужно создать перспективную матрицу, которая отображает один квад на другой.Приведенные выше ссылки показывают, как создать матрицу.Получив матрицу, вы можете отсканировать свой выходной буфер, выполнить преобразование (или, возможно, обратное - в зависимости от того, что вам дают), и это даст вам очки в исходном изображении, из которого вы можете скопировать.

Возможно, было бы проще использовать OpenGL для рисования текстурированного четырехугольника между 4 точками, но в нем не используется GDI, как вы хотели.

...