Найти столбец, строку на двумерной изометрической сетке по координатам пространства экрана x, y (преобразовать уравнение в функцию) - PullRequest
3 голосов
/ 16 июля 2011

enter image description here

Я пытаюсь найти строку, столбец в двумерной изометрической сетке точки пространства экрана (x, y)

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

ТеперьЯ попросил помощи при обмене стеками по математике, чтобы получить уравнение для определения, что параллельные векторы имеют точки x, y по сравнению с черными векторами границы.Ссылка здесь Длина перпендикулярных / параллельных векторов

, но у меня возникают проблемы с преобразованием этого в функцию

В идеале мне нужно достаточно функции, чтобы получить длину обоих красных векторовиз трех наборов точек, x, y конца двух черных векторов и точки в конце красных векторов.

Любой язык хорош, но в идеале javascript

Ответы [ 3 ]

4 голосов
/ 16 июля 2011

Что вам нужно, так это базовое преобразование:

Предположим, что координаты первого черного вектора (x1, x2), а координаты второго вектора (y1, y2).

Следовательно, нахождение красных векторов, попадающих в точку (z1, z2), эквивалентно решению следующей линейной системы:

x1*r1 + y1*r2 = z1
x2*r1 + y2*r2 = z2

или в матричной форме:

   A      x  =  b

/x1 y1\ |r1| = |z1|
\x2 y2/ |r2|   |z2|

          x = inverse(A)*b

Например, пусть черный вектор будет (2, 1) и (2, -1). Соответствующая матрица А будет

2 2
1 -1

и его обратное будет

1/4 1/2
1/4 -1/2

Таким образом, точка (x, y) в исходных координатах сможет быть представлена ​​в альтернативной базе, используя следующую формулу:

(x, y) = (1/4 * x + 1/2 * y)*(2,1)  + (1/4 * x -1/2 * y)*(2, -1)
2 голосов
/ 16 июля 2011

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

var xStep = 50,
    yStep = 30, // roughly matches your image

   pointX = 2*xStep,
   pointY = 0;

По существу, точки любой изометрической сетки попадают на пересеченияизометрическая сетка.Контроллер изометрической сетки:

screenPositionToIsoXY : function(o, w, h){
    var sX   = ((((o.x - this.canvas.xPosition) - this.screenOffsetX) / this.unitWidth ) * 2) >> 0,
        sY   = ((((o.y - this.canvas.yPosition) - this.screenOffsetY) / this.unitHeight) * 2) >> 0,
        isoX = ((sX + sY - this.cols) / 2) >> 0,
        isoY = (((-1 + this.cols) - (sX - sY)) / 2) >> 0;

    // isoX = ((sX + sY) / isoGrid.width) - 1
    // isoY = ((-2 + isoGrid.width) - sX - sY) / 2

    return $.extend(o, {
        isoX : Math.constrain(isoX, 0, this.cols - (w||0)),
        isoY : Math.constrain(isoY, 0, this.rows - (h||0))
    });
},

// ...

isoToUnitGrid : function(isoX, isoY){
    var offset = this.grid.offset(),
        isoX   = $.uD(isoX) ? this.isoX : isoX,
        isoY   = $.uD(isoY) ? this.isoY : isoY;

    return {
        x : (offset.x + (this.grid.unitWidth  / 2) * (this.grid.rows - this.isoWidth + isoX - isoY)) >> 0,
        y : (offset.y + (this.grid.unitHeight / 2) * (isoX + isoY)) >> 0
    };
},
0 голосов
/ 17 июля 2011

Ладно, с помощью других ответов (извините, ребята, не совсем предоставили ответ, за которым я был)

Я представляю свою функцию для нахождения позиции сетки на сетке iso 2d, используя координату мира x, y, где мир x, y - это смещение координат экрана.

WorldPosToGridPos: function(iPosX, iPosY){
    var d = (this.mcBoundaryVectors.upper.x * this.mcBoundaryVectors.lower.y) - (this.mcBoundaryVectors.upper.y * this.mcBoundaryVectors.lower.x);

    var a = ((iPosX * this.mcBoundaryVectors.lower.y) - (this.mcBoundaryVectors.lower.x * iPosY)) / d;
    var b = ((this.mcBoundaryVectors.upper.x * iPosY) - (iPosX * this.mcBoundaryVectors.upper.y)) / d;

    var cParaUpperVec = new Vector2(a * this.mcBoundaryVectors.upper.x, a * this.mcBoundaryVectors.upper.y);
    var cParaLowerVec = new Vector2(b * this.mcBoundaryVectors.lower.x, b * this.mcBoundaryVectors.lower.y);

    var iGridWidth = 40;
    var iGridHeight = 40;

    var iGridX = Math.floor((cParaLowerVec.length() / this.mcBoundaryVectors.lower.length()) * iGridWidth);
    var iGridY = Math.floor((cParaUpperVec.length() / this.mcBoundaryVectors.upper.length()) * iGridHeight);

    return {gridX: iGridX, gridY: iGridY};
},

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

mcBoundaryVectors - это два вектора, определяющие внешние пределы оси x и y изометрической сетки (черные векторы показаны на рисунке выше).

Надеюсь, это поможет кому-нибудь еще в будущем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...