将鼠标坐标转换为3D计划

时间:2012-09-19 21:33:10

标签: javascript jquery 3d drag-and-drop mouse-coordinates

我正在javascript / jquery(基于DOM而不是canvas)中构建某种拖放应用程序。

我们的想法是能够在3D场景上拖动div(以3D旋转的div)。

它适用于2D平面图,问题是当我在3D中旋转场景时,对象位置不会反映实际的鼠标位置,而是以3D形式转换的坐标

图示例子: exemple

EXEMPLE ON JSFIDDLE

我希望对象相对于鼠标的绝对位置移动。

我像这样计算鼠标位置:

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计划的鼠标坐标,但此时无法找到真正的解决方案。

关于此主题的大多数搜索结果都指向面向游戏的语言或canvas / webgl问题。

有什么想法吗?

由于

1 个答案:

答案 0 :(得分:2)

假设您的鼠标位置是绝对屏幕位置,并且您希望直接基于鼠标位置在3D平面上抓取和滑动对象:

您可以将3D目标平面表示为:

  • 3D原点O
  • 两个3D矢量UV,代表U轴和V轴的方向

然后,对应于平面坐标[u,v]的给定3D点是:

point3d P = O + u*U + v*V

然后,您可以将将此特定3D点映射到屏幕的操作组合在一起;这通常使用3D转换矩阵ModelMatrixViewMatrixProjectionMatrix以及由2D屏幕原点origin_2d和2D缩放矢量{{确定的视口转换来描述1}}。要以易于翻转的方式解决问题,可以通过向每个坐标添加scale_2d坐标来将所有内容提升为齐次坐标。此额外坐标充当缩放系数 - 要获得笛卡尔坐标,您需要将同类.w.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 是一个3x3矩阵;你应该能够颠倒它:

TexToScreenMatrix

最后,您可以直接使用UV_2d_hom = [screenpos.x, screenpos.y, 1] * (TexToScreenMatrix)^-1 -> [u, v] = [UV_2d_hom.x, UV_2d_hom.y] / UV_2d_hom.w 坐标,也可以使用它们重新创建3D点[u,v],如上所述。