【问题标题】:Transform screen coordinates to model coordinates将屏幕坐标转换为模型坐标
【发布时间】:2011-12-01 10:07:48
【问题描述】:

我有一些新手问题。

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

我需要将 mouseX 和 mouseY 转换为场景坐标,用于确定我在场景中绘制的对象的 mouseOver 状态。

谁能帮我翻译这些坐标? 提前致谢! /理查德

【问题讨论】:

  • 请发布您的代码!这可能会澄清您的问题;或者我们至少可以重现您的问题。你说你迷路了。丢了怎么办?会发生什么?
  • 这篇文章可能对你有帮助:stackoverflow.com/questions/5470819/…
  • 谢谢!是……我去看看。

标签: mouse scale processing processing.js


【解决方案1】:

不幸的是,这需要修改代码。我会考虑在某个时候将其提交到 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);
};

我希望对遇到此问题的其他人有所帮助。

【讨论】:

  • 谢谢!我会试试这个。看起来我自己也想不通!
  • 嗨 orionr!我已经替换了 processing.js 文件中的方法。但这似乎并不能解决问题。每当我调用方法 modelX(x,y) 和 modelY(x,y) 时,返回值最终都会达到 NaN(每次迭代,数字都会变得越来越小)。似乎在处理过程中调整并记住了一些变量。有什么线索吗?
  • 嗨,Richard - 我自己还没有看到这个问题,并且有一个示例,用户可以在类似地图的世界中滚动和缩放。每次调用 modelX() 和 modelY() 时,是否总是获得新的 mouseX 和 mouseY 值?我注意到您在上面说 modelX(x,y) ,所以想知道您是否在传递之前修改了 mouseX 和 mouseY 值?随意粘贴一些代码,我们可以看看。
  • 你知道Processing是否已经有解决方案吗?不得不使用 hack 很奇怪。 :/ 但是,它似乎确实想要我想要的。谢谢
【解决方案2】:

您是否尝试过其他方法?

例如,假设您处于 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 环境中进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多