将屏幕坐标转换为模型坐标

时间:2011-12-01 10:07:49

标签: mouse scale processing processing.js

我有一些新手问题。

在我的应用程序(processingjs)中,我使用scale()和translate()来允许用户缩放和滚动场景。只要我将比例设置为1.0,我就没有问题。但每当我使用刻度(即刻度(0.5))我就迷失了......

我需要将mouseX和mouseY翻译成场景坐标,我用它来确定我在场景上绘制的对象的mouseOver状态。

有人可以帮我翻译这些坐标吗? 提前致谢! /理查德

2 个答案:

答案 0 :(得分:3)

不幸的是,我需要修改代码。我将在某个时候将其提交给Processing.JS代码库,但这就是我所做的。

首先,您需要使用modelX()和modelY()来获取世界视图中鼠标的坐标。这将是这样的:

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

不幸的是,Processing.JS似乎没有在2D环境中正确计算modelX()和modelY()值。为了纠正我改变功能如下。注意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);
};

我希望能帮助遇到此问题的其他人。

答案 1 :(得分:0)

你尝试过另一种方法吗?

例如,假设您处于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个部分。 这允许您以某种有序的方式移动对象。

当您绘制对象时,您必须提供其尺寸,因此您可以使用objWidthobjHeight

这是交易:您可以制作一个“缩放方法”来编辑对象大小的值。 通过这种方式,您可以绘制更小/更大的对象,而无需编辑任何框架属性。

这是一个简单的例子,因为你的问题不准确。 你也可以[以更复杂的方式]在3D环境中完成它。