首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算机图形学:世界移动

计算机图形学:世界移动
EN

Stack Overflow用户
提问于 2016-05-26 21:37:08
回答 2查看 908关注 0票数 2

我已经实现了

我已经实现了一个应用程序,它能够在屏幕上呈现一个多边形列表,带有一个特定的静态摄像机设置(位置、查看和向上向量),所有这些都是纯Java的,没有OpenGL。

我首先应用模型视图矩阵,然后应用投影到2D矩阵,然后应用视口矩阵。

我还在世界上实现了一些基本的变换矩阵,如平移、X/Y/Z轴围绕lookAt点的旋转和围绕lookAt点的缩放。

我现在想要实现的

我想在这个世界上“移动”。具体来说,我想要用键盘箭头向前、向后、向左和向右导航,并且能够用鼠标查看不同的点。就像在真正的游戏里一样。

我想这是通过每次改变相机参数和渲染世界来完成的。

但有那么简单吗?

在这个世界上移动就是把x,y值加到摄像机的位置上,然后看一个点?

另外,鼠标移动是不是只是在添加x,y来看一点呢?

在任何情况下我都要触摸向上向量吗?

信息丰富的答案,加上更多的相关链接,也将真正有帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-27 06:47:47

您可以通过矩阵的结构化管理来实现此行为。尤其是视图矩阵。在大多数情况下,向x/y位置添加一些东西是不正确的,因为相机可能是旋转的。

让我们用V表示当前视图矩阵。如果要移动摄像机,则必须计算新的视图转换:

代码语言:javascript
复制
V := Translate(-x, -y, -z) * V

,其中Translate(a, b, c)是一个平移矩阵。-x代表左/右方向的运动。-y表示向上/向下。-z表示向前/向后。

如果你想旋转相机,也可以这样做:

代码语言:javascript
复制
V := Rotate(-angle, axis) * V

,其中Rotate(-angle, axis)是一个旋转矩阵。使用x轴的旋转来上下看,用y轴的旋转来看左/右。通常不需要围绕z轴旋转,因为它给相机带来了一个滚转.

大多数参数被否定的原因是视图转换是逆变换。也就是说,他们不定位相机物体,但他们重新定位世界,就像相机在原点一样。

票数 1
EN

Stack Overflow用户

发布于 2016-05-27 07:40:10

首先看一看Understanding 4x4 homogenous transform matrices

  1. 提取你的相机轴向量 如果您查看链接答案中的第一个图像,您将看到向量存储在哪里。注意,如果你有转置布局,那么向量也是转置的。
  2. 运动 运动很容易,你只需add/sub方向矢量到你的相机矩阵的原点。例如,我的相机有Z-作为前进方向。因此,我从矩阵中取Z-axis向量(在我的例子中已经是单位),用速度和时间(运行运动代码的计时器间隔)乘以它。下面是我的移动代码通常的样子: //--------------------------------------------------------------------------- void __fastcall Twin_main::FormKeyDown(TObject *发件人,WORD & key,TShiftState Shift) { //键盘事件调用任何按键keys.set(Key,Shift);//将我的密钥映射中的键设置为按下_redraw=true;//键按意味着场景中的某些内容可能会发生变化,因此重画} //--------------------------------------------------------------------------- void __fastcall Twin_main::FormKeyUp(TObject *Sender,WORD & key,( TShiftState Shift) { //键盘事件调用任何键释放keys.rst( key,Shift);我的密钥映射中的// set键不按} //--------------------------------------------------------------------------- void __fastcall Twin_main::tim_updateTimer(TObject *发件人){ //计时器运行每一个tim_update->区间ms双dt=double( tim_update->Interval )/1000.0;//设定速度和视图模式之间的转换双alfa=2.0*deg;//角速度双v=100000.0/3.6;//运动速度km/hod -> m/s /精度控制if (keys.Shift.Contains(ssAlt )) { v*= 0.1;alfa*= 0.1;} if (keys.Shift.Contains(ssCtrl)) { v*=10.0;alfa*=10.0;} //旋转(局部相机空间) if (keys.get(10 4)){ _redraw=true;eye.rep.lroty(+alfa);} // num8 if (keys.get(10 5)){ _redraw=true;eye.rep.lroty(-alfa);}/ num9 if (keys.get(10 0)){ _redraw=true;eye.rep.lrotx(+alfa);} // num4 if (keys.get( 97)) { _redraw=true;eye.rep.lrotx(-alfa);} // num1 if (keys.get(111)) { _redraw=true;eye.rep.lrotz(+alfa);} // num/ if (keys.get(106)) { _redraw=true;eye.rep.lrotz(-alfa);} // num* if (keys.get( 37)) { _redraw=true;eye.rep.lroty(+alfa);}/左if (keys.get( 39)) { _redraw=true;eye.rep.lroty(-alfa);} //右//移动if (keys.get( 96)) { _redraw=true;eye.rep.lpos_set(vector_ld(0,0.0,-v*dt));} // num0 if (keys.get(110)) { _redraw=true;eye.rep.lpos_set(vector_ld(0,0.0,+v*dt));} // num.if (keys.get( 98)) { _redraw=true;eye.rep.lpos_set(vector_ld(0.0,-v*dt,0.0));} // num2 if (keys.get(101)) { _redraw=true;eye.rep.lpos_set(vector_ld(0.0,+v*dt,0.0));}/ num5 if (keys.get(10 2)){ _redraw=true;eye.rep.lpos_set(vector_ld(-v*dt,0.0,0.0));} // num6 if (keys.get( 99)) { _redraw=true;eye.rep.lpos_set(+v*dt,0.00.0);}/ num3 if (keys.get( 38)) { _redraw=true;eye.rep.lpos_set(vector_ld(0.00.0,-v*dt));}/ up if (keys.get( 40)) { _redraw=true;eye.rep.lpos_set(vector_ld(0,0.0,+v*dt));} // down keys.rfskey();//只为高级键盘设备做一些事情,如果(_redraw) {eye.rep.lpos_set();}}//------------------------- keys是我的类,为16位密钥代码中的每一个都保存了一个位bool,允许我一次处理多个按下的键。eye.rep是我的类,包含正变换矩阵和逆变换矩阵。其成员lpos_set将三维矢量从局部坐标转换为全局坐标,并将其设置为矩阵原点。它的效果与我提到的上述过程相同。deg在弧度上只是恒定的1度,而lrot?是下一颗子弹的局部旋转。
  3. 轮调 我不使用欧拉角,因为我恨他们。他们得到的小故障需要以不同的方式处理电线杆,并且经常造成问题。你玩过什么游戏吗?相机的角度旋转被卡住了,不允许你在你想要的地方旋转?或者甚至是反向?然后,这是由于欧拉角用于相机。 我使用本地轮转lrot?代替(参见链接答案如何工作)。他们没有界限,也没有小故障。你需要记住的唯一一件事就是准确性。如果你是旋转矩阵多次,你失去了精度。因此,每几个旋转都保证了它的正交性或正交性。为此,您只需使用交叉乘积使轴再次垂直,并将其长度设置为1或任何您使用的。我在我的矩阵类中有一个计数器,递增每一个变化,当它碰到一个回放时,正交性就恢复了。

正如你所看到的,我用数字板来做运动,箭头是用来左/右转,向前/向后的。现在大多数人使用WSAD,但这对我来说是非常不舒服的。代码取自我的一个VCL应用程序,所以您需要更改事件以匹配您的应用程序。

还可以添加鼠标处理程序.如果你需要Joystick看

但我怀疑它是否适用于JAVA,是否适用于Windows。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37471430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档