我在javascript/jquery (基于DOM,而不是画布)中构建某种拖放应用程序。
其想法是能够在3D场景(在3D中旋转的div )上拖动div。
它在2D平面上工作,问题是当我在3D中旋转场景时,物体的位置并不反映实际的鼠标位置,而是在3D中转换的坐标。
举例说明:
我希望物体相对于鼠标的绝对位置移动。
我计算鼠标的位置如下:
document.addEventListener(gestureMove, function (event) {
if (mouseDown == true) {
event.preventDefault();
moveX = (event.pageX - $('#scene').offset().left);
moveY = (event.pageY - $('#scene').offset().top);
}
#scene {
width: 1000px;
height: 1000px;
-webkit-transform-style: preserve-3d;
-webkit-transform: rotateX( 35deg );
}
早期的解决方案是根据初始位置计算鼠标位置和对象之间的差异,并在拖动期间将其添加到对象位置。这是可行的,但动画真的是波涛汹涌,一点也不顺利。
我确信有一种更简单的方法可以获得相对于3D计划的鼠标坐标,但在这一点上没有找到真正的解决方案。
关于这个主题的大多数搜索结果都指向面向游戏的语言,或画布/webgl问题。
有什么想法吗?
谢谢
发布于 2012-09-19 14:40:55
假设您的鼠标位置是一个绝对的屏幕位置,并且您希望根据鼠标位置在3D平面上抓取和滑动一个对象:
您可以将您的三维目标平面表示为:
O
U
和V
,表示U轴和V轴的方向。然后,与平面坐标[u,v]
对应的给定的三维点是:
point3d P = O + u*U + v*V
然后,您可以组合将这个特定的3D点映射到屏幕上的操作;这通常由3D转换矩阵ModelMatrix
、ViewMatrix
和ProjectionMatrix
以及由2D屏幕原点origin_2d
和2D缩放矢量scale_2d
确定的视口转换来描述。要以一种容易逆转的方式解决这个问题,请将所有内容推广到齐次坐标,向每个坐标添加一个.w
-coordinate。这个额外的坐标充当一个缩放因子--要获得笛卡尔坐标,您需要将齐次.x
和.y
值除以.w
值:
P_hom = [u, v, 1] * [U.x, U.y, U.z, 0] = [u, v, 1] * TexMatrix
[V.x, V.y, V.z, 0]
[O.x, O.y, O.z, 1]
P_clip_hom = P_hom * ModelMatrix * ViewMatrix * ProjectionMatrix
= P_hom * ModelViewProjectionMatrix
screenpos_hom = P_clip_hom * [scale_2d.x 0 0] = P_clip_hom * PortMatrix
[ 0 scale_2d.y 0]
[ 0 0 0]
[origin_2d.x origin_2d.y 1]
So, screenpos_hom = [u, v, 1] * TexMatrix * ModelViewProjectionMatrix * PortMatrix
= [u, v, 1] * TexToScreenMatrix
-> [screenpos.x, screenpos.y] = [screenpos_hom.x, screenpos_hom.y] / screenpos_hom.w
请注意,TexToScreenMatrix
是一个3x3矩阵;您应该能够反转它:
UV_2d_hom = [screenpos.x, screenpos.y, 1] * (TexToScreenMatrix)^-1
-> [u, v] = [UV_2d_hom.x, UV_2d_hom.y] / UV_2d_hom.w
最后,您可以直接使用[u,v]
坐标,也可以使用它们重新创建上面描述的3D点P
。
https://stackoverflow.com/questions/12503219
复制