专栏首页每日一篇技术文章SceneKit - 将屏幕坐标转换至游戏场景oc+swift版

SceneKit - 将屏幕坐标转换至游戏场景oc+swift版

本节学习目标

如何将屏幕2D坐标转换至3D游戏场景中去

oc 源码

- (SCNVector3)convertToScenOfPoint:(CGPoint)point
{
    CGFloat Z_Far = 0.1;
    CGFloat Screen_Aspect =  [UIScreen mainScreen].bounds.size.width > 400 ? 0.3 : 0.0;
    double Y = tan((double)(self.sceneView.pointOfView.camera.fieldOfView/180/2)*M_PI) * (double)(Z_Far-Screen_Aspect);
    double X = tan((double)(self.sceneView.pointOfView.camera.fieldOfView/2/180)*M_PI) * (double)(Z_Far-Screen_Aspect) * (double)(self.view.bounds.size.width/self.view.bounds.size.height);
    CGFloat alphaX = 2 *  X / self.view.bounds.size.width;
    CGFloat alphaY = 2 *  Y / self.view.bounds.size.height;
    float x = -(CGFloat)X + point.x * alphaX;
    float y = (CGFloat)Y - point.y * alphaY;
    SCNVector3 target = SCNVector3Make((float)(x), (float)(y),(float)(-Z_Far));
    SCNVector3 convertPoint = [self.sceneView.pointOfView convertVector:target toNode:self.sceneView.scene.rootNode];
    NSLog(@"convertPoint X: %f,Y:%f,Z:%f", convertPoint.x, convertPoint.y, convertPoint.z);
    return convertPoint;
}

swift

 /// 将屏幕上的点转化到3D场景中去
func convertToScenOf(point: CGPoint) -> SCNVector3{
     let Z_Far:CGFloat = 0.1
    var Screen_Aspect : CGFloat = UIScreen.main.bounds.size.width > 400 ? 0.3 : 0.0
     // 计算屏幕边缘的距离
    let Y = tan(Double(self.pointOfView!.camera!.fieldOfView/180/2)*Double.pi) * Double(Z_Far-Screen_Aspect)
    let X = tan(Double(self.pointOfView!.camera!.fieldOfView/2/180)*Double.pi) * Double(Z_Far-Screen_Aspect) * Double(self.bounds.size.width/self.bounds.size.height)
     let alphaX = 2 *  CGFloat(X) / self.bounds.size.width
     let alphaY = 2 *  CGFloat(Y) / self.bounds.size.height
     let x = -CGFloat(X) + point.x * alphaX
     let y = CGFloat(Y) - point.y * alphaY
     let target = SCNVector3Make(Float(x), Float(y), Float(-Z_Far))
     return self.pointOfView!.convertPosition(target, to:scene.rootNode)
}

注意

Z_Far:是要放置在屏幕后面多远的距离

上线应用ARFinger 即使用了此方式,欢迎各位下载试玩!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VR+全景播放器+头控讲解-06

    在UIView上面布局我们可以使用UIButton UIView UIImageView等,但是是在3D场景中,我们不能使用UIView,我们要使用平面几何当视...

    酷走天涯
  • SceneKit - AR换装应用解决方案

    由于今年是AR元年,在苹果推出的ARKit框架之后,各行各业都在马不停蹄的玩起了创意,希望在自己的应用基础上加入AR的元素

    酷走天涯
  • VR+全景播放器+头控讲解-07

    酷走天涯
  • CSS3背景

    小胖
  • C++核心准则C.180:使用联合体节约内存

    A union allows a single piece of memory to be used for different types of object...

    面向对象思考
  • 字符串展开(递归)- HDU 1274

    常用纱线的品种一般不会超过25种,分别可以用小写字母表示不同的纱线,例如:abc表示三根纱线的排列;重复可以用数字和括号表示,例如:2(abc)表示abcabc...

    ACM算法日常
  • 2018-10-09 pywifi模块

    安装方法:pip3 install pywifi 安装位置:/usr/local/lib/python3.5/dist-packages/pywifi注意事项:...

    用户1733354
  • iOS的WebView——WKWebView

    Oceanlong
  • Spring速查手册(二)——Bean的作用域

    Bean的四种作用域 单例(Singleton):整个应用中,只创建一个bean。 原型(Prototype):每次注入或请求要给bean的时候都创建一个新的...

    大闲人柴毛毛
  • Spring原理:10个Spring&SpringBoot高阶用法,你是否清楚?

    通过ApplicationContextAware实现,在bean实例化后,经过Aware扫描时,发现实现了ApplicationContextAware接口,...

    lyb-geek

扫码关注云+社区

领取腾讯云代金券