我正在iOS上使用SceneKit开发一些html" target="_blank">代码,在我的代码中,我想确定全局z平面上的x和y坐标,其中z为0.0,而x和y由轻击手势确定。我的设置如下:
override func viewDidLoad() {
super.viewDidLoad()
// create a new scene
let scene = SCNScene()
// create and add a camera to the scene
let cameraNode = SCNNode()
let camera = SCNCamera()
cameraNode.camera = camera
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light.type = SCNLightTypeAmbient
ambientLightNode.light.color = UIColor.darkGrayColor()
scene.rootNode.addChildNode(ambientLightNode)
let triangleNode = SCNNode()
triangleNode.geometry = defineTriangle();
scene.rootNode.addChildNode(triangleNode)
// retrieve the SCNView
let scnView = self.view as SCNView
// set the scene to the view
scnView.scene = scene
// configure the view
scnView.backgroundColor = UIColor.blackColor()
// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
let gestureRecognizers = NSMutableArray()
gestureRecognizers.addObject(tapGesture)
scnView.gestureRecognizers = gestureRecognizers
}
func handleTap(gestureRecognize: UIGestureRecognizer) {
// retrieve the SCNView
let scnView = self.view as SCNView
// check what nodes are tapped
let p = gestureRecognize.locationInView(scnView)
// get the camera
var camera = scnView.pointOfView.camera
// screenZ is percentage between z near and far
var screenZ = Float((15.0 - camera.zNear) / (camera.zFar - camera.zNear))
var scenePoint = scnView.unprojectPoint(SCNVector3Make(Float(p.x), Float(p.y), screenZ))
println("tapPoint: (\(p.x), \(p.y)) scenePoint: (\(scenePoint.x), \(scenePoint.y), \(scenePoint.z))")
}
func defineTriangle() -> SCNGeometry {
// Vertices
var vertices:[SCNVector3] = [
SCNVector3Make(-2.0, -2.0, 0.0),
SCNVector3Make(2.0, -2.0, 0.0),
SCNVector3Make(0.0, 2.0, 0.0)
]
let vertexData = NSData(bytes: vertices, length: vertices.count * sizeof(SCNVector3))
var vertexSource = SCNGeometrySource(data: vertexData,
semantic: SCNGeometrySourceSemanticVertex,
vectorCount: vertices.count,
floatComponents: true,
componentsPerVector: 3,
bytesPerComponent: sizeof(Float),
dataOffset: 0,
dataStride: sizeof(SCNVector3))
// Normals
var normals:[SCNVector3] = [
SCNVector3Make(0.0, 0.0, 1.0),
SCNVector3Make(0.0, 0.0, 1.0),
SCNVector3Make(0.0, 0.0, 1.0)
]
let normalData = NSData(bytes: normals, length: normals.count * sizeof(SCNVector3))
var normalSource = SCNGeometrySource(data: normalData,
semantic: SCNGeometrySourceSemanticNormal,
vectorCount: normals.count,
floatComponents: true,
componentsPerVector: 3,
bytesPerComponent: sizeof(Float),
dataOffset: 0,
dataStride: sizeof(SCNVector3))
// Indexes
var indices:[CInt] = [0, 1, 2]
var indexData = NSData(bytes: indices, length: sizeof(CInt) * indices.count)
var indexElement = SCNGeometryElement(
data: indexData,
primitiveType: .Triangles,
primitiveCount: 1,
bytesPerIndex: sizeof(CInt)
)
var geo = SCNGeometry(sources: [vertexSource, normalSource], elements: [indexElement])
// material
var material = SCNMaterial()
material.diffuse.contents = UIColor.redColor()
material.doubleSided = true
material.shininess = 1.0;
geo.materials = [material];
return geo
}
如你看到的。我有一个三角形,该三角形的高度为4个单位,宽为4个单位,并设置在以x,y(0.0,0.0)为中心的z平面(z =
0)上。相机是默认的SCNCamera,它沿负z方向看,我将其放置在(0,0,15)处。zNear和zFar的默认值分别为1.0和100.0。在我的handleTap方法中,我获取水龙头的x和y屏幕坐标,并尝试在z
= 0.0的情况下查找x和y全局场景坐标。我正在使用unprojectPoint的电话。
unprojectPoint的文档指示
取消投影其z坐标为0.0的点将返回近裁剪平面上的一个点;取消投影z坐标为1.0的点将返回远裁剪平面上的点。
尽管并没有特别说明,对于两者之间的点,近平面和远平面之间存在线性关系,但我做出了这一假设,并将screenZ的值计算为z
=的近平面和远平面之间的距离百分比。 0平面位于。要查看答案,我可以单击三角形的角附近,因为我知道它们在全局坐标中的位置。
我的问题是,当我开始更改相机上的zNear和zFar裁剪平面时,我没有获得正确的值,也没有获得一致的值。所以我的问题是,我该怎么做?最后,我将创建一个新的几何并将其放置在与用户单击位置相对应的z平面上。
在此先感谢您的帮助。
3D图形管线中的典型深度缓冲区不是线性的。透视划分导致归一化设备坐标中的深度处于不同的比例。(另请参见此处。)
因此,您要输入的z坐标unprojectPoint
实际上并不是您想要的。
那么,如何找到与世界空间中的平面匹配的归一化深度坐标呢?好吧,如果该平面垂直于相机(您的相机)是有帮助的。然后,您要做的就是在该平面上投影一个点:
let projectedOrigin = gameView.projectPoint(SCNVector3Zero)
现在,您可以在3D视图+归一化深度空间中找到世界原点的位置。要将2D视图空间中的其他点映射到该平面上,请使用此向量的z坐标:
let vp = gestureRecognizer.locationInView(scnView)
let vpWithZ = SCNVector3(x: vp.x, y: vp.y, z: projectedOrigin.z)
let worldPoint = gameView.unprojectPoint(vpWithZ)
这样可以在世界空间中获得一个点,该点将单击/点击位置映射到z = 0平面,position
如果要向用户显示该位置,则适合用作节点的位置。
(请注意,这种方法仅在映射到垂直于相机视线方向的平面上才有效。如果要将视线坐标映射到不同方向的表面上,则in中的归一化深度值vpWithZ
将不会恒定)
我正在尝试记录来自iPhone加速度计(我自己的iPhone5s)的数据,并使用在屏幕上为该数据设置标签,其中data是我要记录的特定轴的值。为此,我设置了一个CMMotionManager并开始记录加速度计数据,并且我有一个定时器可以不断更新标签中的文本。但是,我从Xcode收到一个错误:“致命错误:在展开可选值时意外发现为nil”。以下是相关代码: 当我更改accelX时,错误停止。文本赋值给
问题内容: 我正在尝试使我的javascript与快速代码交互,但不幸的是我没有成功。 目前,我只是尝试更改标题的颜色并显示一条消息,如下面的代码所示。 这是我的( index.html )代码: 这是我的( main.js -JavaScript )代码: 这是我的( ViewController.swift )代码: 问题答案: 您已正确设置了所有内容,但没有将实例分配给。由于配置包含Java
问题内容: 我只想检索UserAccount类中的某些列,所以我有以下代码: 我得到了空值作为回报。但是,如果我注释掉setProjections,我将获得具有所有属性的用户。在这种情况下,如何正确使用setProjection? 问题答案: 它返回一个Object数组,因此代码应为:
问题内容: 我不知道我在哪里错了:/。当我运行这段代码时,我得到的只是一个空白元素。我似乎无法让insertRule方法执行任何操作(甚至不会产生错误)。我想念什么吗? 问题答案: 这有点令人困惑,但是您的代码确实可以工作,只是您看不到返回的XML树中插入的规则。 为了验证您的代码是否有效,您可以执行两个测试: 运行上面的代码片段,您可以看到CSS规则确实适用。并且属性也在控制台中更改。 当浏览器
问题内容: 如何使用从类路径中查找递归资源? 例如 在“目录”中查找所有资源:想象一下 不幸的是,这只会检索到恰好该“目录”。 所有资源都已命名(递归) 但这返回一个空。 还有一个额外的问题:与有什么不同? 问题答案: 没有办法递归搜索类路径。您需要知道资源的完整路径名才能以这种方式检索它。该资源可能位于文件系统中的目录中,也可能位于jar文件中,因此它不像执行“类路径”的目录列表那样简单。您将需
问题内容: 我最近开始使用ScriptManager。我有一个通过JavaScript填充的ASP.NET DropDownList控件。但是,我正在使用事件验证。因此,如果我不使用下拉菜单中的“ RegisterForEventValidation”调用,则会遇到以下错误。我怎么知道在第二个参数中设置什么值(我有“值”)?我正在通过JavaScript填充下拉列表,因此我不知道后面的代码中包含哪