Просмотр полной версии : Из экранных координат в координаты 2.5D проекции
s3dworld
01.03.2012, 19:50
Всем доброго вечера!
Из координат 2.5D проекции в экранные координаты я перевожу следующим образом:
screenX=offset+x*w/2-y*w/2;
screenY=x*h/2+y*h/2;
Теперь надо реализовать обратное преобразование. На листочке накидал систему уравнений. На скорую руку попробовал её решить и вот что у меня получилось:
x=(2*mouseX*h-2*offset*h+2*mouseY*w)/(w*h+w);
y=(2*mouseY-x*h)/h;
Но что-то результат далеко не верный. Есть ли у кого-то готовая формула?
Stitch512
01.03.2012, 21:51
x = (w*screenY+h*screenX-h*offset)/(h*w);
y = -(h*screenX-h*offset-w*screenY)/(h*w);
Добавлено через 1 минуту
Это не готовая формула, это решения вашего уравнения (в Maple решил для гарантии).
Silicium
01.03.2012, 21:54
Как это у вас получилось? из первых ур-ний следуют вот такие:
x=((screenX-offset)/w+screenY/h)
y=(screenY/h-(screenX-offset)/w)
вероятно, screenX->mouseX.
Если кому-то не нравятся мои уравнения, прошу писать здесь и сразу.
Stitch512
01.03.2012, 21:56
(в Maple решил для гарантии)
В плане решения систем уравнений я склонен ему доверять, как то не вижу смысла решать на бумажке если есть возможность автоматизировать процесс.
Silicium
01.03.2012, 21:59
не вижу смысла решать на бумажке если есть возможность автоматизировать процесс
Вот это вы зря. Доверяй, но проверяй. Maple неоднократно подводил (простых уравнений это, конечно не касается, но все же)
Stitch512
01.03.2012, 22:00
Если кому-то не нравятся мои уравнения, прошу писать здесь и сразу.
А это решения для тех уравнений которые вы прислали)
screenX = -1/2*y*w+offset;
screenY = 1/2*y*h;
Добавлено через 1 минуту
Вот это вы зря. Доверяй, но проверяй. Maple неоднократно подводил (простых уравнений это, конечно не касается, но все же)
Ну не знаю, меня еще ни разу не подвел, да это и не сложные уравнения.
Silicium
01.03.2012, 22:09
А это решения для тех уравнений которые вы прислали)
Не удивительно, что у вас ничего не получилось первый раз)
Добавлено через 1 минуту
Из "моих" непосредственно получаются "ваши"
Stitch512
01.03.2012, 22:11
Не удивительно, что у вас ничего не получилось первый раз)
Эээ... В смысле... Какой первый раз. Да и че спорить то, пущай человек подставит оба варианта решений и проверит какой рабочий.
Silicium
01.03.2012, 22:12
А, прошу прощения, я вас с автором перепутал=)
Добавлено через 36 секунд
Причем, хочу заметить, что наши с вами решения полностью эквиваленты.
Добавлено через 1 минуту
Если мое решение домножить и поделить на w*h, получится ваше
Stitch512
01.03.2012, 22:17
Кстати оба варианта рабочие - выдают одни и те же решения при одинаковых входных данных)
Добавлено через 1 минуту
ну то есть это, собственно, одни и те же формулы
s3dworld
02.03.2012, 13:34
Всем доброго дня!
Ни одна формула не заработала как надо. Первая формула рассчитывала строки не верно. Тыкаю в клетку 4, а она показывает 14. Вторая формула была не точна. Тыкаю на одну и ту же клетку, но в разные места, и значения целые были разные. А третья формула показывает значение строки 800, когда тыкаю к строку 0. Сейчас попробую сам пересчитать всё это с листочком и ручкой, а пока считаю, дам Вам информацию для размышления.
Все тайлы карты я рисую в один большой Bitmap. Для его рассчёта я определяю положения крайних точек:
// Рассчитываем размер изображения
var imageWidth:uint=0;
var imageHeight:uint=0;
var mapX1:int=0;
var mapY1:int=0;
var mapX2:int=0;
var mapY2:int=0;
mapX1=(0*Game.fieldWidth/2)-((map.mapRows-1)*Game.fieldWidth/2);
mapY1=(0*Game.fieldHeight/2)+(0*Game.fieldHeight/2);
mapX2=((map.mapColumns-1)*Game.fieldWidth/2)-(0*Game.fieldWidth/2)+Game.fieldWidth;
mapY2=((map.mapColumns-1)*Game.fieldHeight/2)+((map.mapRows-1)*Game.fieldHeight/2)+Game.fieldHeight;
imageWidth=(-1*mapX1)+mapX2;
imageHeight=mapY1+mapY2;
var bitmapData:BitmapData=new BitmapData(imageWidth,imageHeight,true,0);
Теперь у меня есть область для заполнения тайлов. И в цикле я её заполняю:
for(var j:uint=0;j<map.mapRows;j++)
{
for(var i:uint=0;i<map.mapColumns;i++)
{
var matrix:Matrix=new Matrix();
matrix.translate((-1*mapX1)+(i*Game.fieldWidth/2)-(j*Game.fieldWidth/2),(i*Game.fieldHeight/2)+(j*Game.fieldHeight/2));
bitmapData.draw(mapLoad.GetData(map.fieldObjects[j * map.mapColumns + i].id),matrix);
}
}
bitmap=new Bitmap(bitmapData);
Как видите, я к каждому тайлу прибавляю по оси X значение, обратное началу моего квадрата, так, чтобы тайлы выводились правильно (а то бы они начали рисоваться с самого левого края изображения, а надо почти от середины). Именно это обратное значение я и запоминаю как смещение:
offsetScreenX=-1*mapX1;
Теперь на этот Bitmap я вешаю событие мышки MOUSE_DOWN и определяю координаты куда мы тыкнули через localX и localY. Как реализовать обратное преобразование?
Добавлено через 26 минут
Вот для размышления. Красный прямоугольник - это Bitmap, по которому мышкой тыкаем.
http://xmages.net/storage/10/1/0/d/4/upload/a5ac3373.png
Stitch512
02.03.2012, 14:40
а пока считаю, дам Вам информацию для размышления.
Спасибо тебе, Белый Господин, мы будем денно и нощно размышлять во славу твою....
Лошадь пусть размышляет - у нее голова большая.
Вот (http://***********/29047542), если интересно, когда-то начинал делать проект с изометрией, формулы отличаются, но рабочие.
s3dworld
02.03.2012, 16:51
Есть рисунок, на который должны быть выведены изометрические тайлы. Количество колонок и столбцов на карте задано:
public var mapRows:uint=30;
public var mapColumns:uint=30;
Ширина и высота тайлов задана:
public var fieldWidth:uint=100;
public var fieldHeight:uint=54;
Рассчитывается размер изображения со всеми выведенными тайлами:
var imageWidth:uint=0;
var imageHeight:uint=0;
var mapX1:int=0;
var mapY1:int=0;
var mapX2:int=0;
var mapY2:int=0;
mapX1=(0*Game.fieldWidth/2)-((map.mapRows-1)*Game.fieldWidth/2);
mapY1=(0*Game.fieldHeight/2)+(0*Game.fieldHeight/2);
mapX2=((map.mapColumns-1)*Game.fieldWidth/2)-(0*Game.fieldWidth/2)+Game.fieldWidth;
mapY2=((map.mapColumns-1)*Game.fieldHeight/2)+((map.mapRows-1)*Game.fieldHeight/2)+Game.fieldHeight;
imageWidth=(-1*mapX1)+mapX2;
imageHeight=mapY1+mapY2;
offsetScreenX=-1*mapX1;
var bitmapData:BitmapData=new BitmapData(imageWidth,imageHeight,true,0);
Рисуются все тайлы:
for(var j:uint=0;j<map.mapRows;j++)
{
for(var i:uint=0;i<map.mapColumns;i++)
{
var matrix:Matrix=new Matrix();
matrix.translate(offsetScreenX+(i*Game.fieldWidth/2)-(j*Game.fieldWidth/2),(i*Game.fieldHeight/2)+(j*Game.fieldHeight/2));
bitmapData.draw(mapLoad.GetData(map.fieldObjects[j * map.mapColumns + i].id),matrix);
}
}
bitmap=new Bitmap(bitmapData);
Получается такая вот карта:
http://xmages.net/storage/10/1/0/c/f/upload/a60fa20d.png
При этом каждый тайл ограничен прямоугольной областью:
http://xmages.net/storage/10/1/0/c/9/upload/439f3c83.png
Но все они лежат в картинке:
http://xmages.net/storage/10/1/0/a/c/upload/a87822b7.png
На картинку подписано событие MOUSE_DOWN. Нужно определить столбец и строку тайла, на который тыкнули мышкой. Есть какие-то идеи?
Stitch512
02.03.2012, 17:01
Вы пример то хоть смотрели. Там есть общая формула преобразования из экранных координат в изометрические. А по изометрическим координатам, зная шаг сетки, определить строку и столбец думаю труда не составит.
s3dworld
02.03.2012, 19:55
Stitch512
Посмотрел. Даже скопировал функцию перевода. Но не помогло(((
MikroAcse
02.03.2012, 19:57
hitTestPoint? Узнать какой тайл под мышкой...
Stitch512
02.03.2012, 20:04
Посмотрел. Даже скопировал функцию перевода. Но не помогло(((
Ну вам для начала нужно определиться с системой координат в изометрической проекции, где какие оси и куда направлены. А вы как то странно поступили, сначала просто нарисовали картинку а потом по ней пытаетесь вычислить координаты... Какие координаты, относительно чего, где вообще начало, где оси... Перевод в изометрическую и обратно - это по факту набор преобразований. У вас же ничего похожего на математику я не заметил. Так что, или копайте изометрию, либо, как заметил MikroAcse, - hitTestPoint, но не рекомендую ибо это как то через ж...
Добавлено через 1 минуту
hitTestPoint? Узнать какой тайл под мышкой...
Не сработает, все тайлы блитятся в одну bitmapData.
По-моему во 2-м и 3-м посте просто потеряли 2-ку. Всё справа ещё умножить на 2. Должно сработать. Если нет, то проверьте и нарисуйте на ваших картинках, где находится screenX и screenY, если x = y = 0. Должна быть точка в верхнем углу.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.