vector - 如何在 Apple SceneKit 中确定 SCNPlane 的法线向量
问题描述
我有一个 SCNode,它是使用 SCNPlane 几何图形动态创建的,以使用 SceneKit 绘制平面。
如何确定该平面的法线向量?
这是一个展示我尝试过的东西的游乐场。我附上了绘制的结果场景的屏幕截图。我不认为有任何圆柱体代表在这个红色平面的法线向量处获得的向量。
//: Playground - noun: a place where people can play
import UIKit
import SceneKit
import PlaygroundSupport
// Set up the scene view
let frame = CGRect(
x: 0,
y: 0,
width: 500,
height: 300)
let sceneView = SCNView(frame: frame)
sceneView.showsStatistics = true
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
sceneView.scene = SCNScene()
// Setup our view into the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 3)
sceneView.scene!.rootNode.addChildNode(cameraNode)
// Add a plane to the scene
let plane = SCNNode(geometry: SCNPlane(width: 3,height: 3))
plane.geometry?.firstMaterial!.diffuse.contents = UIColor.red.withAlphaComponent(0.5)
plane.geometry?.firstMaterial?.isDoubleSided = true
sceneView.scene!.rootNode.addChildNode(plane)
/*
normalSource = [SCNGeometrySource geometrySourceWithData:data
semantic:SCNGeometrySourceSemanticNormal
vectorCount:VERTEX_COUNT
floatComponents:YES
componentsPerVector:3 // nx, ny, nz
bytesPerComponent:sizeof(float)
dataOffset:offsetof(MyVertex, nx)
dataStride:sizeof(MyVertex)];
*/
let dataBuffer = plane.geometry?.sources(for: SCNGeometrySource.Semantic.normal)[0].data
let colorArray = [UIColor.red, UIColor.orange, UIColor.yellow, UIColor.green, UIColor.blue, UIColor.systemIndigo, UIColor.purple, UIColor.brown, UIColor.black, UIColor.systemPink]
let sceneGeometrySource = dataBuffer!.withUnsafeBytes {
(vertexBuffer: UnsafePointer<SCNVector3>) -> SCNGeometrySource in
let sceneVectors = Array(UnsafeBufferPointer(start: vertexBuffer, count: dataBuffer!.count/MemoryLayout<SCNVector3>.stride))
var i=0
for vector in sceneVectors{
let cyl = SCNCylinder(radius: 0.05, height: 3)
cyl.firstMaterial!.diffuse.contents = colorArray[i].withAlphaComponent(0.8)
let lineNode = SCNNode(geometry: cyl)
lineNode.eulerAngles = vector
sceneView.scene!.rootNode.addChildNode(lineNode)
}
return SCNGeometrySource(vertices: sceneVectors)
}
PlaygroundSupport.PlaygroundPage.current.liveView = sceneView
解决方案
在“计算三角形的法线”中的苹果文档https://developer.apple.com/documentation/accelerate/working_with_vectors中,您可以找到解决方案。您只需要不在一条线上的 3 个点,然后使用它:
下面的代码定义了三角形的三个顶点:
let vertex1 = simd_float3(-1.5, 0.5, 0) let vertex2 = simd_float3(1, 0, 3) let vertex3 = simd_float3(0.5, -0.5, -1.5) 计算三角形法线的第一步是创建两个由顶点之间的差定义的向量——代表三角形的两条边:
let vector1 = vertex2 - vertex3 let vector2 = vertex2 - vertex1 simd_cross 函数返回垂直于您传递的两个向量的向量。在这个例子中,返回的向量是三角形的法线。因为法线代表一个方向,所以可以对值进行归一化得到单位向量:
让 normal = simd_normalize(simd_cross(vector1, vector2))
推荐阅读
- python - 如果输入狗,猫或鸟,我如何让我的程序显示动物发出的噪音
- git - Azure DevOps 触发器在 release/{version} 分支上构建
- javascript - VueJS $emit 无法将数据推送到父级
- bash - Shell 脚本:[参数过多
- javascript - Angular不会从另一个分配属性值
- c - 单周期 44.1kHz 采样 1kHz 正弦波 c
- delphi - TVirtualStringTree,树结构的位置
- haskell - Haskell Monads 内部
- python - 在 scikit-learn 的多类文本分类包中使用 predict() 和 predict_proba() 的结果不一致
- python - AttributeError:模块'cv2.cv2'没有属性'samples'