WebGL自学教程——WebGL示例:11. 交互:更好的鼠标控制

 

11. 交互:更好的鼠标控制

 

    在《9. 交互:这次我们用鼠标》中,键盘和鼠标都只控制了立方体绕z轴和x轴的旋转。在从正面观察的情况下,总是无法同时显示立方体的三个面。本章,我们介绍用鼠标拖动实现立方体的3D旋转。

    一个旋转对应一个方向向量。如果把所有的方向向量转换为固定的模长,假设为r,并且把向量(x,y,z)当成一个3D坐标,那么,把这些坐标聚集在一起,就形成了一个以(0,0,0)为球心,r为半径的球体。假设我们的鼠标是3D的,那么鼠标在这个球体表面上的每个点击,都将对应一个唯一的3D坐标,并且,该坐标直接和一个方向向量对应。

    但问题是,鼠标是2D的。因此,我们需要一种方法,能够将2D的鼠标坐标(x,y)转换为3D的(X,Y,Z)。

    我们先反过来看一下,3D球体上的坐标在2D中情况。为了简单和方便解说,我们用正视投影,也不考虑任何变换。上面提及的球体经正视投影到2D坐标系后,生成了一个以(0,0)为圆心,r为半径的圆。也就是说,这个2D的圆,其实是和3D中的球对应的。圆中的任何一点(x,y)都和球体表面某个或某几个(X,Y,Z)对应。想象一下,在2D坐标的(x,y)处(圆的内部或圆周上),画出一条和z轴平行的直线。如果直线和球相切,则在Z=0这个平面上,有一个唯一的交点,该交点的3D坐标可以确定为(x,y,0)。如果该直线和球不相切,则必定和球体有两个交点,一个在+Z范围中,一个在-Z范围中。你可以同时处理这两个点或选取其中任何之一。作为解释,还有本章示例,我选取的是+Z范围中的这个点。因为是正视投影,所以,2D坐标系中的xy轴的值和3D坐标系中的xy轴的值相同,唯一欠缺的是z轴坐标。但我们知道球体有个公式,r2 = x2 + y2 + z2。于是我们可以计算出z为正负sqrt(r2 - x2 - y2)。于是,我们的3D坐标完整了,于是,你想进行实际操作了?先别急。想想实际应用中情况,我们的视见区是(w,h)的大小,是一个矩形;通常也不会把鼠标限定在一个圆形范围。也就是说,鼠标通过拖动进行3D旋转时,其位置可能会超出圆周,如下图所示:

其中,大蓝点表示鼠标相对于坐标系原点的位置(X,Y)。此时,我们需要对它进行处理,一种简单的方法是把它对应到圆周上,如上图中的大红点(直线(0,0)(X,Y)和圆周的交点)。交点的求法真地很简单,任何学过初中数学的人都会,结果已在上图中的下方给出。

    如果再仔细思考一下,我们其实可以发现,如果把上图中的圆替换成椭圆,或者说,把前面提到的圆球映射到视见区的椭圆,那么我们就可以更好地处理用户拖动(可以处理更大地拖动范围,更加精确地计算出旋转方向)。如果你足够NB,甚至可以把整个视见区和圆球进行关联。

    有了上面的这些知识,我们再看看具体的情况。我们想要的操作过程是,用户鼠标按下,表示开始拖动旋转;按住不放并移动鼠标,就通过移动的位移计算出3D偏移方向;松开鼠标键,表示拖动旋转结束。在这一过程中,我们以鼠标按下时的位置为圆心(它对应初始方向V0(0,0,1));鼠标的位移都相对于该圆心,通过该位移,计算出当前要旋转方向V1。通过V0和V1,我们可以计算出这两个方向之间的夹角α;还可以计算出原点、点V0、点V1所形成的平面的法线Vn。当前的旋转于是可以表示为绕Vn旋转了α角度。

    α相关的公式为:V0.V1 = ||V0||.||V1||.cosα

    平面法线用现成的js函数gltGetNormalVector获得,或者用V0V1的叉积算得。

    在示例中,我暂时去除了键盘的旋转控制,在更久以后的一些综合示例中,会再把它加上。为了方便观看当前的旋转方向,我为立方体的一个表面增加了一个蓝色的圆锥。该圆锥的顶点相对于坐标系原点(0,0,0)。立方体的顶点也相对于坐标系原点(0,0,0)。你可能会奇怪,都是相对于坐标系原点(0,0,0),那它们绘画出来之后难道不会互相覆盖吗?好吧,这是我的错,之前没有介绍。一般,我们对某一物体进行建模,都是使用一个完全独立的坐标系,我们称之为模型坐标系或物体坐标系,或者叫作模型空间或物体空间。在把物体进行组合时,我们需要把物体坐标转换到世界坐标。想象一下盖房子的过程。设计师绘画图纸的时候,绝对不会使用东经、西经和南纬、北纬之类的地球坐标系,而是直接定好比例尺,以某个点为坐标原点。建筑人员看到图纸后,在将要建造房子的地方,会将图纸上的坐标原点对应到适合的地球坐标(东经多少度、北纬多少度)。地球坐标,就是我们3D中的世界坐标,无论你从哪边看,怎么看,它都在那儿,永不改变。能够改变的,是房子的方位以及我们看世界的角度。它们具有对称性:斜着看房子和把房子斜着盖,最终落在我们严重的情景是一样的。回到正题,看看之前的立方体顶点及顶点着色器中的输出位置,非常巧合,立方体的物体坐标系的原点,被映射到世界坐标系的原点;并且,立方体被按1:1的比例生成到世界中。

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312">
<script type="text/javascript" src="glMatrix-0.9.5.js"></script>

<script type="text/javascript" src="glt.js"></script><!--glt系列函数已转存在glt.js文件中-->

<script id

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值