加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 某个z深度的xy位置

发布时间:2020-12-14 19:35:00 所属栏目:Java 来源:网络整理
导读:在处理( java方言)中有方法screenX,screenY(和screenZ,但我们现在跳过它). 假设我有一个xyz = 50,100,500的对象.然后使用screenX和screenY,你现在可以在画布上显示它们的位置. float x = screenX(50,500); float y = screenY(50,500); 这里是参考: http://p
在处理( java方言)中有方法screenX,screenY(和screenZ,但我们现在跳过它).

假设我有一个xyz = 50,100,500的对象.然后使用screenX和screenY,你现在可以在画布上显示它们的位置.

float x = screenX(50,500);
float y = screenY(50,500);

这里是参考:
http://processing.org/reference/screenX_.html

我感兴趣的是反方法.
例如,我想在x = 175和y = 100的画布上使用球体到apear.球体的z值应为700.那么实际的x和y位置在z = 700处是什么才能使它在画布上显示为175,100?

所以方法是float unscreenX(float x,float y,float z),它会返回x值.

我的数学/编程技巧不是那么先进(让我们称之为糟糕)(我更像是设计师)所以我正在寻求一些帮助.我已经准备好在加工板上问过了,但是这里有更多的人对矩阵等有更深入的了解.

处理中的常规screenX方法可以在这里找到:
https://github.com/processing/processing/blob/master/core/src/processing/opengl/PGraphicsOpenGL.java

public float screenX(float x,float z) {
    return screenXImpl(x,y,z);
  }

protected float screenXImpl(float x,float z) {
    float ax =
      modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03;
    float ay =
      modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13;
    float az =
      modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23;
    float aw =
      modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33;
    return screenXImpl(ax,ay,az,aw);
  }


  protected float screenXImpl(float x,float z,float w) {
    float ox =
      projection.m00*x + projection.m01*y + projection.m02*z + projection.m03*w;
    float ow =
      projection.m30*x + projection.m31*y + projection.m32*z + projection.m33*w;

    if (nonZero(ow)) {
      ox /= ow;
    }
    float sx = width * (1 + ox) / 2.0f;
    return sx;
  }

对于y和对于z(我不理解z,但让我们忽略它).
我认为这可能会对如何反转它提供一些见解.

modelview和projection是一个3d矩阵,代码在这里:
https://github.com/processing/processing/blob/master/core/src/processing/core/PMatrix3D.java
但我想这是非常基本和常见的.

我也曾在加工板上发帖,因为你从来不知道.它解释了我想要的一点点不同.
http://forum.processing.org/topic/unscreenx-and-unscreeny

对于描述这篇文章的标签,我没有去具体原因我可以想象一个程序员谁从未使用过java但是曾经使用过c和具有矩阵经验的程序员仍然能够提供一个很好的答案.

希望有人能提供帮助.

解决方法

我强烈建议你研究一些线性代数或矩阵数学用于3d图形.它既有趣又简单,但比SO答案要长一点.我会尝试:)免责声明:我不知道你正在使用的API!

看起来你正在为一个位置返回3个坐标(通常称为顶点).但是你也提到了一个投影矩阵,该函数有4个坐标.通常,着色器或API将为顶点采用4个坐标. X,Y,Z,W上.要在屏幕上显示它们,它会执行以下操作:

xscreen = x/w
yscreen = y/w
zbuffer = z/w

这很有用,因为你可以选择w.如果你只是做2d绘图,你可以把w = 1.但是,如果你正在做3D并想要一些透视效果,你想要除以相机的距离.这就是投影矩阵的用途.它主要取你的点的z,其中z表示与相机的距离并将其置于w中.它也可以扩展一些东西,比如视野.

回顾一下您发布的代码,这正是最后一个ScreenXImpl函数所做的.
它应用一个投影矩阵,它主要只是将z移动到w,然后除以w.最后它做了一个额外的比例并从(-1,1)偏移到(0,widhtinpixels),但我们可以忽略它.

现在,我为什么要谈论这些东西呢?你想要做的就是获得给定的xscreen,yscreen,zbuffer的x,z坐标,对吗?好吧,诀窍就是倒退了.为了做到这一点,你需要牢牢抓住前进:)

倒退有两个问题:1)你真的知道或关心zbuffer值吗? 2)你知道投影矩阵是做什么的吗?
1)让我们说我们不在乎.这有很多可能的值,所以我们可能只选择一个.对于2)你将不得不看看它做了什么.一些投影矩阵可能只取(x,z,w)和输出(x,1).那将是2d.或(x,y z,1)将是等距的.但从视角来看,它通常会(x,1,z).加上一些缩放等等.

我刚注意到你的第二个screenXImpl已经将x,w传递到下一个阶段.这有时是有用的,但是对于w将为1的所有实际情况.

在这一点上,我意识到我在解释事情上很糟糕. :)你真的应该拿起那本线性代数书,我从这一本书中学到了:http://www.amazon.com/Elementary-Linear-Algebra-Howard-Anton但它带来了一个很好的讲座,所以我不知道它有多么有用.

无论如何!让我们变得更实际.回到你的代码:screenXImpl的最后一个功能.我们现在知道输入w = 1并且ow = ~z和ox = ~x;这里的波浪线意味着一些规模加上一些偏移.我们必须开始的屏幕x是~ox / ow. (1/2,*宽..这是波浪线的意思).现在我们回到1)…如果你想要一个特殊的盎司 – 现在选择一个.否则,我们可以挑选任何.对于渲染,在相机前挑选任何东西并且易于使用可能是有意义的.喜欢1.

protected float screenXImpl(float x,float w==1) {
float ox = 1*x + 0*y + 0*z + 0*w; // == x
float ow = 0*x + 0*y + 1*z + 0*w; // == z == 1

ox /= ow; // == ox

float sx = width * (1 + ox) / 2.0f;
return sx;
}

WTF? sx =宽*(1牛)/ 2?我为什么不这么说呢?好吧,我放在那里的所有零都可能不是零.但它最终会变得如此简单.可能不是那些人.我试图展示你必须做出的重要假设才能回归.现在它应该像从sx回到牛一样容易.

那是困难的部分!但你仍然需要从最后一个功能到第二个功能.我想第一个第二个很容易. :)该函数正在进行线性矩阵变换.这对我们有好处.它需要输入四个值(x,z)和(w = 1)隐式输出四个其他值(ax,aw).我们可以弄清楚如何手动返回那里!我必须在学校这样做..四个未知数,四个方程式.你知道ax,aw …求解x,z你得到w = 1是免费的!非常可能和良好的运动,但也很乏味.好消息是这些方程的编写方式称为矩阵. (x,1)* MODELMATRIX =(ax,aw).真的很方便,因为我们可以找到MODELMATRIX ^ -1.它被称为逆!就像1/2是2乘以实数的倒数,或-1是加1的倒数.你真的应该读一下这很有趣而不是很难,顺便说一下:).
无论如何,使用任何标准库来获得模型矩阵的逆.可能类似于modelView.Inverse().然后用它做同样的功能然后你倒退.简单!

现在,为什么我们之前没有对PROJECTION矩阵做同样的事情呢?很高兴你问!那一个需要4个输入(x,w)并且只吐出三个输出(screenx,screeny,zbufferz).所以没有做出一些假设我们无法解决它!一个直观的方式来看,如果你有一个3d点,你在二维屏幕上投影,那将会有很多可能的解决方案.所以我们必须选择一些东西.而且我们不能使用方便的矩阵逆函数.

如果这有点有帮助,请告诉我.我觉得它不是,但我写得很开心!另外google for unproject in processing给出了这个:http://forum.processing.org/topic/read-3d-positions-gluunproject

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读