Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用鼠标旋转球体_Javascript_Math_Opengl Es_Geometry_Webgl - Fatal编程技术网

Javascript 用鼠标旋转球体

Javascript 用鼠标旋转球体,javascript,math,opengl-es,geometry,webgl,Javascript,Math,Opengl Es,Geometry,Webgl,我可以确定用户在地球仪上的位置 当用户第一次单击鼠标按钮时,我可以存储他们单击的位置;我们把它叫做pin 然后,当他们拖动鼠标时,我想把pin放在鼠标光标下 下面的一些代码似乎大致将pin放在鼠标指针下,但不能正确地维护地球仪;它随机闪烁和旋转。有时,它完全翻转轴,使地球仪瞬间前后颠倒 function evtPos(evt) { if(!scene.ortho) return null; var x = lerp(scene.ortho[0],scene.ortho[1],e

我可以确定用户在地球仪上的位置

当用户第一次单击鼠标按钮时,我可以存储他们单击的位置;我们把它叫做
pin

然后,当他们拖动鼠标时,我想把
pin
放在鼠标光标下

下面的一些代码似乎大致将
pin
放在鼠标指针下,但不能正确地维护地球仪;它随机闪烁和旋转。有时,它完全翻转轴,使地球仪瞬间前后颠倒

function evtPos(evt) {
    if(!scene.ortho) return null;
    var x = lerp(scene.ortho[0],scene.ortho[1],evt.clientX/canvas.width),
        y = lerp(scene.ortho[3],scene.ortho[2],evt.clientY/canvas.height), // flipped
        sqrd = x*x+y*y;
    return (sqrd > 1)?
        null:
        mat4_vec3_multiply(mat4_inverse(scene.mvMatrix),[x,y,Math.sqrt(1-sqrd)]);
}

function onMouseDown(evt) {
    pin = evtPos(evt);
}

function onMouseMove(evt,keys,isMouseDown) {
    if(!isMouseDown) return;
    var pt = evtPos(evt);
    if(pin == null) pin = pt;
    if(pt == null) return;
    var d = vec3_sub(pt,pin),
        rotx = Math.atan2(d[1],d[2]),
        roty = (d[2] >= 0)?
            -Math.atan2(d[0] * Math.cos(rotx),d[2]):
            Math.atan2(d[0] * Math.cos(rotx),-d[2]),
        rotz = Math.atan2(Math.cos(rotx),Math.sin(rotx)*Math.sin(roty));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotx,[1,0,0]));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(roty,[0,1,0]));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotz,[0,0,1]));
}

function onMouseUp(evt) {
    pin = null;
}
此外,随着时间的推移,错误似乎会累积,并且
引脚
会越来越远离鼠标指针。我想我应该以某种方式完全计算
mvMatrix
,而不是通过每个事件的大量samll增量


我希望用户能够拖动地球仪来自然导航。我发现所有旋转球体的代码都使用固定速度,例如箭头键,而不是将球体“固定”在鼠标指针下。Unity有一个四元数函数。FromToRotation(fromPos,toPos),看起来很有希望,但源代码不可用。

实现这一点的方法之一是。甚至还有可用的,所以您不需要自己动手。

实现这一点的方法之一是。甚至还有可用的,所以您不需要自己动手。

从这个问题判断,您似乎希望StackOverflow为您实施项目。你尝试了什么?你被困在哪里了?如果你至少不尝试,你可能会发现寻求帮助是徒劳的。@Popleak,你只要告诉我先尝试什么,我就会有一些事情要调查和尝试。有时,甚至开始解决问题的方法都是不明显的。我已经输入了一些代码,但我知道它有很大的缺陷,而且不可简单地修改。我建议在每次鼠标移动事件中完全重新计算旋转矩阵——也就是说,找到第二个
pin
,并使用其相对于第一个
pin
的相对位置进行变换,然后在每一帧重新传输。从这个问题判断,你似乎想要StackOverflow为你实现你的项目。你尝试了什么?你被困在哪里了?如果你至少不尝试,你可能会发现寻求帮助是徒劳的。@Popleak,你只要告诉我先尝试什么,我就会有一些事情要调查和尝试。有时,甚至开始解决问题的方法都是不明显的。我已经输入了一些代码,但我知道它有很大的缺陷,而且不能简单地修改。我只是建议在每次鼠标移动事件中完全重新计算旋转矩阵——也就是说,找到第二个
pin
,并使用它相对于第一个
pin
的相对位置进行变换,并在每一帧重新变换。