Преобразовать координаты экрана в координаты модели - PullRequest
2 голосов
/ 01 декабря 2011

У меня какой-то вопрос новичка.

В моем приложении (processingjs) я использую scale () и translate (), чтобы позволить пользователю масштабировать и прокручивать сцену. Пока я держу масштаб на 1.0, у меня нет проблем. НО всякий раз, когда я использую шкалу (то есть масштаб (0,5)), я теряюсь ...

Мне нужно перевести mouseX и mouseY в координаты сцены, которые я использую для определения состояния mouseOver объекта, который я рисую на сцене.

Кто-нибудь может мне помочь, как перевести эти координаты? Заранее спасибо! / Richard

Ответы [ 2 ]

3 голосов
/ 29 декабря 2011

К сожалению, для меня это потребовало модификации кода. В какой-то момент я посмотрю на отправку этого в репозиторий кода Processing.JS, но вот что я сделал.

Во-первых, вы захотите использовать modelX () и modelY (), чтобы получить координаты мыши в представлении о мире. Это будет выглядеть так:

float model_x = modelX(mouseX, mouseY);
float model_y = modelY(mouseX, mouseY);

К сожалению, Processing.JS неправильно рассчитывает значения modelX () и modelY () в 2D-среде. Чтобы исправить это, я изменил функции следующим образом. Обратите внимание на тест для mv.length == 16 и раздел в конце для 2D:

p.modelX = function(x, y, z) {
  var mv = modelView.array();
  if (mv.length == 16) {
    var ci = cameraInv.array();
    var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];
    var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];
    var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];
    var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];
    var ox = 0, ow = 0;
    var ox = ci[0] * ax + ci[1] * ay + ci[2] * az + ci[3] * aw;
    var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw;
    return ow !== 0 ? ox / ow : ox
  }
  // We assume that we're in 2D
  var mvi = modelView.get();
  // NOTE that the modelViewInv doesn't seem to be correct in this case, so
  // having to re-derive the inverse
  mvi.invert();
  return mvi.multX(x, y);
};
p.modelY = function(x, y, z) {
  var mv = modelView.array();
  if (mv.length == 16) {
    var ci = cameraInv.array();
    var ax = mv[0] * x + mv[1] * y + mv[2] * z + mv[3];
    var ay = mv[4] * x + mv[5] * y + mv[6] * z + mv[7];
    var az = mv[8] * x + mv[9] * y + mv[10] * z + mv[11];
    var aw = mv[12] * x + mv[13] * y + mv[14] * z + mv[15];
    var oy = ci[4] * ax + ci[5] * ay + ci[6] * az + ci[7] * aw;
    var ow = ci[12] * ax + ci[13] * ay + ci[14] * az + ci[15] * aw;
    return ow !== 0 ? oy / ow : oy
  }
  // We assume that we're in 2D
  var mvi = modelView.get();
  // NOTE that the modelViewInv doesn't seem to be correct in this case, so
  // having to re-derive the inverse
  mvi.invert();
  return mvi.multY(x, y);
};

Я надеюсь, что это поможет кому-то еще, кто имеет эту проблему.

0 голосов
/ 19 февраля 2013

Вы пробовали другой метод?

Например, предположим, что вы находитесь в 2D-среде, вы можете «отобразить» весь кадр в виде матрицы. Примерно так:

int fWidth = 30;
int fHeight = 20;
float objWidth = 10;
float objHeight = 10;

void setup(){
  fWidth = 30;
  fHeight = 20;
  objWidth = 10;
  objHeight = 10;
  size(fWidth * objWidth, fHeight * objHeight);
}

В этом случае у вас будет кадр 300 * 200, но разделенный на 30 * 20 секций. Это позволяет вам несколько упорядоченно перемещать ваши объекты.

Когда вы рисуете объект, вы должны указать его размеры, чтобы вы могли использовать objWidth и objHeight.

Вот в чем дело: вы можете создать «метод масштабирования», который будет редактировать значения размеров объекта. Таким образом, вы нарисовали объект меньшего / большего размера без редактирования какого-либо свойства фрейма.

Это простой пример из-за вашего неточного вопроса. Вы можете сделать это [более сложными способами], в том числе и в 3D-среде.

...