gpt4 book ai didi

swift - 如何计算垂直平面可见部分的四边形?

转载 作者:行者123 更新时间:2023-12-04 11:35:46 26 4
gpt4 key购买 nike

我的目标是计算 anchor 定到某些 ARPlaneAnchor 的垂直平面的“可见”部分。并用四边形表示,如下图所示:
Piture
我目前的方法是基于很少的 HitTest ,不幸的是,这似乎没有给我令人满意的结果。
首先,当我检测到 ARPlaneAnchor我加个大隐形SCNNode到其主节点。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

let planeNode = SCNNode(geometry: SCNPlane(width: 100.0, height: 100.0))
planeNode.name = "infinite_plane"

planeNode.position = SCNVector3(planeAnchor.center.x, planeAnchor.center.y, planeAnchor.center.z)
planeNode.eulerAngles = SCNVector3(-0.5 * .pi, 0, 0)

planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.clear

node.addChildNode(planeNode)

node.enumerateChildNodes { childNode, _ in
childNode.removeFromParentNode()
}
}
然后,当需要计算垂直平面的可见部分时(时间无关紧要,可以在一些屏幕触摸之后或每次渲染新帧时)我取屏幕中心并执行一些 HitTest .
let center = CGPoint(x: sceneView.bounds.midX, y: sceneView.bounds.midY)
let hitTestResults = sceneView.hitTest(center, types: [.existingPlaneUsingGeometry, .estimatedVerticalPlane])
if let hitTestResult = hitTestResults.first,
let hitAnchor = hitTestResult.anchor,
let hitNode = sceneView.node(for: hitAnchor) {

let width = sceneView.bounds.width
let height = sceneView.bounds.height
// A B
// C D
guard let aPosition = sceneView.hitTest(CGPoint(x: 0, y: 0)).first?.worldCoordinates,
let bPosition = sceneView.hitTest(CGPoint(x: width, y: 0)).first?.worldCoordinates,
let cPosition = sceneView.hitTest(CGPoint(x: 0, y: height)).first?.worldCoordinates,
let dPosition = sceneView.hitTest(CGPoint(x: width, y: height)).first?.worldCoordinates else {
return
}
let geometry = SCNGeometry.polygon(vertices: [aPosition, bPosition, dPosition, cPosition])
let node = SCNNode(geometry: geometry)
node.geometry?.firstMaterial?.diffuse.contents = UIColor.green
node.geometry?.firstMaterial?.isDoubleSided = true
sceneView.scene.rootNode.addChildNode(node)
}
extension SCNGeometry {

static func polygon(vertices: [SCNVector3]) -> SCNGeometry {
let source = SCNGeometrySource(vertices: vertices)

var indices = vertices.indices.map { UInt32($0) }
indices.insert(UInt32(vertices.count), at: 0)

let data = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size)

let element = SCNGeometryElement(
data: data,
primitiveType: .polygon,
primitiveCount: 1,
bytesPerIndex: MemoryLayout<Int32>.size
)

return SCNGeometry(sources: [source], elements: [element])
}
}
在这里我停了下来。绘制的多边形似乎并不代表垂直平面的可见部分。
问题是,我的估计在哪里错误,我应该如何正确检测垂直平面的“可见”部分?

最佳答案

试试这个方法:

extension ViewController: ARSCNViewDelegate {

func renderer(_ renderer: SCNSceneRenderer,
didAdd node: SCNNode,
for anchor: ARAnchor) {

guard let planeAnchor = anchor as? ARPlaneAnchor
else { return }

let width = CGFloat(planeAnchor.extent.x)
let height = CGFloat(planeAnchor.extent.z)

let myPlane = SCNPlane(width: width,
height: height)

myPlane.materials.first?.diffuse.contents = UIColor(white: 0.0,
alpha: 0.5)

let planeNode = SCNNode(geometry: myPlane)
let x = CGFloat(planeAnchor.center.x)
let y = CGFloat(planeAnchor.center.y)
let z = CGFloat(planeAnchor.center.z)

planeNode.position = SCNVector3(x, y, z)
planeNode.eulerAngles.x = -Float.pi / 2

node.addChildNode(planeNode)
}

func renderer(_ renderer: SCNSceneRenderer,
didUpdate node: SCNNode,
for anchor: ARAnchor) {

guard let planeAnchor = anchor as? ARPlaneAnchor,
let planeNode = node.childNodes.first,
let myPlane = planeNode.geometry as? SCNPlane
else { return }

let width = CGFloat(planeAnchor.extent.x)
let height = CGFloat(planeAnchor.extent.z)
myPlane.width = width
myPlane.height = height

let x = CGFloat(planeAnchor.center.x)
let y = CGFloat(planeAnchor.center.y)
let z = CGFloat(planeAnchor.center.z)
planeNode.position = SCNVector3(x, y, z)
}
}

关于swift - 如何计算垂直平面可见部分的四边形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65063069/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com