Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Из экранных координат в координаты 2.5D проекции (http://www.flasher.ru/forum/showthread.php?t=176086)

s3dworld 01.03.2012 19:50

Из экранных координат в координаты 2.5D проекции
 
Всем доброго вечера!

Из координат 2.5D проекции в экранные координаты я перевожу следующим образом:

Код AS3:

screenX=offset+x*w/2-y*w/2;
screenY=x*h/2+y*h/2;

Теперь надо реализовать обратное преобразование. На листочке накидал систему уравнений. На скорую руку попробовал её решить и вот что у меня получилось:

Код AS3:

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

Код AS3:

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

Цитата:

Если кому-то не нравятся мои уравнения, прошу писать здесь и сразу.
А это решения для тех уравнений которые вы прислали)
Код AS3:

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. Для его рассчёта я определяю положения крайних точек:

Код AS3:

// Рассчитываем размер изображения
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);

Теперь у меня есть область для заполнения тайлов. И в цикле я её заполняю:

Код AS3:

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 значение, обратное началу моего квадрата, так, чтобы тайлы выводились правильно (а то бы они начали рисоваться с самого левого края изображения, а надо почти от середины). Именно это обратное значение я и запоминаю как смещение:

Код AS3:

offsetScreenX=-1*mapX1;

Теперь на этот Bitmap я вешаю событие мышки MOUSE_DOWN и определяю координаты куда мы тыкнули через localX и localY. Как реализовать обратное преобразование?

Добавлено через 26 минут
Вот для размышления. Красный прямоугольник - это Bitmap, по которому мышкой тыкаем.

http://xmages.net/storage/10/1/0/d/4...d/a5ac3373.png

Stitch512 02.03.2012 14:40

Цитата:

а пока считаю, дам Вам информацию для размышления.
Спасибо тебе, Белый Господин, мы будем денно и нощно размышлять во славу твою....

Лошадь пусть размышляет - у нее голова большая.

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

s3dworld 02.03.2012 16:51

Есть рисунок, на который должны быть выведены изометрические тайлы. Количество колонок и столбцов на карте задано:

Код AS3:

public var mapRows:uint=30;
public var mapColumns:uint=30;

Ширина и высота тайлов задана:

Код AS3:

public var fieldWidth:uint=100;
public var fieldHeight:uint=54;

Рассчитывается размер изображения со всеми выведенными тайлами:

Код AS3:

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);

Рисуются все тайлы:

Код AS3:

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...d/a60fa20d.png

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

http://xmages.net/storage/10/1/0/c/9...d/439f3c83.png

Но все они лежат в картинке:

http://xmages.net/storage/10/1/0/a/c...d/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.

-De- 02.03.2012 22:03

По-моему во 2-м и 3-м посте просто потеряли 2-ку. Всё справа ещё умножить на 2. Должно сработать. Если нет, то проверьте и нарисуйте на ваших картинках, где находится screenX и screenY, если x = y = 0. Должна быть точка в верхнем углу.


Часовой пояс GMT +4, время: 01:06.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.