ios - Scenekit Pan 2D Translation to Orthographic 3D only horizo​​ntal

标签 ios math 3d translation scenekit

我在 3D 编程方面遇到了更多的数学问题,希望您能帮助我!

我正在尝试使用具有等角角度的 Scenekit 创建 3D 游戏。

这段代码创建了我的正交相机:

var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.name = "Camera"
cameraNode.position = SCNVector3Make(-5.0, -5.0, 10.0)
cameraNode.eulerAngles = SCNVector3Make(PI / 3.0, 0.0, -PI / 4.0)
cameraNode.camera?.usesOrthographicProjection = true
cameraNode.camera?.orthographicScale = 7.0
scene.rootNode.addChildNode(cameraNode)

现在我想使用平移手势移动相机,产生滚动感。为了使这成为可能,相机不应该垂直移动,只能水平移动。屏幕上的触摸位置和 3D 世界中未投影的位置在移动时应保持不变。

我考虑过将 2D 转换为 3D 差异并忽略垂直分量。这段代码确实有效并且几乎产生了预期的结果,但速度不正确。如果我平移,相机似乎会加速并且无法正确 react :

var previousTranslation = CGPointMake(0.0, 0.0)

func pan(gesture: UIPanGestureRecognizer)
{
    let view = self.view as SCNView
    let translation = gesture.translationInView(view)
    let location = gesture.locationInView(view)

    let diffTrans = translation - previousTranslation
    previousTranslation = translation

    let cameraNode = scene.rootNode.childNodeWithName("Camera", recursively: false)

    let worldPointTrans = view.unprojectPoint(SCNVector3Make(-Float(diffTrans.x), -Float(diffTrans.y), 0.0))
    let worldPoint0 = view.unprojectPoint(SCNVector3Make(0.0, 0.0, 0.0))

    var diff = worldPointTrans - worldPoint0
    diff.x = diff.x / Float(cameraNode!.camera!.orthographicScale)
    diff.y = diff.y / Float(cameraNode!.camera!.orthographicScale)
    diff.z = 0
    cameraNode?.position += diff
}

有人知道一种复杂的方法可以将屏幕转换计算为水平 3D 转换,而忽略垂直轴吗?

提前谢谢你:)

编辑: 平底锅现在可用于水平平移。但不是垂直的,因为我将 z 轴上的差异设置为零。

最佳答案

我找到了自己的解决方案。!

我正在计算手势起始位置 (P1-P2) 的射线和平移位置 (Q1-Q2) 的射线。现在我有两条射线,我让它们都与 XY 平面相交以接收点 P0 和 Q0

P0 和 Q0 的区别是未投影的翻译。

这种技术应该也适用于非正交相机,但我还没有测试过。

在我看来它是有效的,但如果有人能从数学上证实这个假设,我会很高兴读到它:)

代码如下:

 var previousLocation = SCNVector3(x: 0, y: 0, z: 0)

func pan(gesture: UIPanGestureRecognizer)
{
    let view = self.view as SCNView
    let translation = gesture.translationInView(view)

    let location = gesture.locationInView(view)
    let secLocation = location + translation

    let P1 = view.unprojectPoint(SCNVector3(x: Float(location.x), y: Float(location.y), z: 0.0))
    let P2 = view.unprojectPoint(SCNVector3(x: Float(location.x), y: Float(location.y), z: 1.0))

    let Q1 = view.unprojectPoint(SCNVector3(x: Float(secLocation.x), y: Float(secLocation.y), z: 0.0))
    let Q2 = view.unprojectPoint(SCNVector3(x: Float(secLocation.x), y: Float(secLocation.y), z: 1.0))

    let t1 = -P1.z / (P2.z - P1.z)
    let t2 = -Q1.z / (Q2.z - Q1.z)

    let x1 = P1.x + t1 * (P2.x - P1.x)
    let y1 = P1.y + t1 * (P2.y - P1.y)

    let P0 = SCNVector3Make(x1, y1,0)

    let x2 = Q1.x + t1 * (Q2.x - Q1.x)
    let y2 = Q1.y + t1 * (Q2.y - Q1.y)

    let Q0 = SCNVector3Make(x2, y2, 0)

    var diffR = Q0 - P0
    diffR *= -1

    let cameraNode = view.scene!.rootNode.childNodeWithName("Camera", recursively: false)

    switch gesture.state {
    case .Began:
        previousLocation = cameraNode!.position
        break;
    case .Changed:
        cameraNode?.position = previousLocation + diffR
        break;
    default:
        break;
    }
}

Red is screen translation, Blue is world translation

关于ios - Scenekit Pan 2D Translation to Orthographic 3D only horizo​​ntal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27346757/

相关文章:

function - 如何在 Matlab 中计算某个点的函数?

c# - 绘制至少一个像素宽的对象

php - mysql显示所有行的计算平均值

ios - UICollectionView 只返回一个部分?

ios - Swift/iOS : Analyzing (lldb) crash, Paypal iOS SDK

ios - 当我只有 html 时,我可以创建新版本的 phonegap 应用程序并将其作为更新发布吗?

ios - 如何以最高精度比较小数点后30位的双数?

3d - 快速计算外心坐标和三角形高

3d - 如何在 OpenSCAD 中放置对象(使其在 Z 轴上齐平以进行 3D 打印)

ios - 如何将多个参数与 performSelector : method? 一起使用