преобразовать декартову ширину и высоту в изометрическую

Я пытаюсь создать изометрическую игру в графической библиотеке SDL.

При рендеринге в SDL требуется исходный прямоугольник и целевой прямоугольник. Исходный прямоугольник — это часть текстуры, которую вы загрузили, которую вы хотите визуализировать, а целевой прямоугольник — это область на экране, которую вы визуализируете. Прямоугольники просто состоят из 4 свойств, положения X, положения Y, ширины и высоты.

Теперь скажите, что у меня есть прямоугольный прямоугольник с этими координатами:

X = 20, Y = 10, ширина = 16, высота = 16

Теперь скажите, что я хотел преобразовать это в Изометрические. Для преобразования координат X и Y я бы использовал:

isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;

Теперь я не понимаю, что бы я сделал, чтобы преобразовать декартову ширину и высоту в изометрическую ширину и высоту, чтобы создать иллюзию того, что порт обзора перемещается на 45 градусов в одну сторону и на 30 градусов вниз, создавая изометрический вид.

РЕДАКТИРОВАТЬ:
Я хотел бы немного уточнить свой вопрос, поэтому, когда я преобразовываю декартовы координаты в изометрические, я изменяю это:http://i.stack.imgur.com/I79yK.png
к этому:http://i.stack.imgur.com/ZCJg1.png. Итак, теперь я пытаюсь выяснить, как вращать плитки, чтобы они все совпали, и как мне нужно отрегулировать высоту и ширину, чтобы это произошло.

0

Решение

Для начала вам понадобятся следующие операции для преобразования в и изометрические координаты:

isoX = carX + carY;
isoY = carY - carX / 2.0;

carX = (isoX - isoY) / 1.5;
carY = isoX / 3.0 + isoY / 1.5;

прямоугольные углы в верхнем левом и нижнем правом углу становятся 120 градусов, остальные два угла становятся 60 градусов. нижний правый угол становится нижним, верхний левый угол становится верхним. это также предполагает, что у увеличивается с ростом, а х увеличивается с направлением (если ваша система отличается, поменяйте знаки соответственно). посредством подстановки вы можете проверить, что эти операции являются обратными.

для прямоугольника вам нужно преобразовать 4 точки — углы — поскольку они не будут «прямоугольными» для целей SDL (это будет параллелограмм). это легче увидеть численно.

во-первых, присвойте углам имена какого-либо рода. я предпочитаю по часовой стрелке, начиная с левого нижнего угла — эта координата должна быть известна как C1, и имеет связанные X1 и Y1, остальные будут C2-4.

C2 - C3
|    |
C1 - C4

затем вычислите их декартовы координаты …

X1 = RECT.X;
Y1 = RECT.Y;

X2 = X1; // moving vertically
Y2 = RECT.Y + RECT.HEIGHT;

X3 = RECT.X + RECT.WIDTH;
Y3 = Y2; // moving horizontally

X4 = X3; // moving vertically
Y4 = RECT.Y;

и, наконец, применить преобразование индивидуально к каждой координате, чтобы получить координаты I1, I2, I3, I4 …

iX1 = X1 + Y1;
iY1 = Y1 - X1 / 2.0;
// etc

и в результате вы получите экранные координаты I1-4, которые принимают эту форму:

    I2
/    \
I1      I3
\    /
I4

Но в отличие от этого некачественного изображения, углы для I4 и I2 будут ~ 127 градусов, а для I1 и I3 — ~ 53 градуса. (это может быть точно настроено, чтобы быть точно 60/120, и зависит от коэффициента 2.0 для carX при вычислении isoY — это должно быть sqrt (3), а не 2.0, но достаточно близко)

если вы используете обратное преобразование, вы можете превратить координаты I1-4 в C1-4 или определить координату мира из экранной координаты и т. д.

реализация камеры / видового экрана становится немного сложнее, если только поначалу, но это выходит за рамки того, о чем просили, поэтому я не пойду туда (без дальнейших подталкиваний) …

(Редактировать) Что касается SDL …

SDL не «хорошо играет» с обобщенными преобразованиями. Я не использовал его, но его интерфейс удивительно похож на GDI (windows), с которым я играл ранее для игрового движка и столкнулся с этой проблемой (вращение + масштабирование текстур).

Существует одна (кажется, нестандартная) функция SDL, которая выполняет масштабирование и вращение текстур, но делает это в неправильном порядке, поэтому всегда поддерживает перспективу изображения, и здесь это не то, что нужно.

Как вы уже видели, базовая геометрия будет в порядке, потому что это заливки и линии, которые не нужно масштабировать, а только позиционировать. Но для текстур … Вам нужно будет либо написать код для визуализации текстуры по одному пикселю за раз, либо использовать комбинацию преобразований (масштабирование после поворота), либо наслоение (рисование изометрического квадрата с альфа-маской и рендеринг предварительно вычисленная текстура) и так далее …

Или, конечно, если это вариант для вас, используйте что-то подходящее для необработанных данных геометрии и текстуры, например OpenGL / Direct3D. Лично я бы пошел с OpenGL / SFML для чего-то вроде этого.

0

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

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

X = 20, Y = 10, ширина = 16, высота = 16

как ты сказал

isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;

так

isometricX1 = cartX1 - cartY1;
isometricY1 = (cartX1 + cartY1) / 2;

а также

isometricWidth = std::abs(isometricY - isometricY1)

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

РЕДАКТИРОВАТЬisometricWidth нашла расстояние между двумя точками, а не ширину и высоту
еще одно замечание: вам понадобятся противоположные углы (да, я понимаю, что другой парень, вероятно, гораздо лучший ответ: P)

0

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