Vector 如何在Apple SceneKit中确定SCNPlane的法向量

Vector 如何在Apple SceneKit中确定SCNPlane的法向量,vector,scenekit,scngeometry,Vector,Scenekit,Scngeometry,我有一个SCNode,它是使用SCNPlane几何体动态创建的,用于使用SceneKit绘制平面 如何确定该平面的法向量 这是一个操场,展示了我的尝试。我已经附上了一个屏幕截图的结果是画的场景。我不认为有任何圆柱,它们代表的是在这个红色平面的法向量上得到的向量 /:操场-名词:人们可以玩耍的地方 导入UIKit 导入SceneKit 导入PlaygroundSupport //设置场景视图 设frame=CGRect( x:0,, y:0, 宽度:500, 身高:300) 让sceneView

我有一个SCNode,它是使用SCNPlane几何体动态创建的,用于使用SceneKit绘制平面

如何确定该平面的法向量

这是一个操场,展示了我的尝试。我已经附上了一个屏幕截图的结果是画的场景。我不认为有任何圆柱,它们代表的是在这个红色平面的法向量上得到的向量

/:操场-名词:人们可以玩耍的地方
导入UIKit
导入SceneKit
导入PlaygroundSupport
//设置场景视图
设frame=CGRect(
x:0,,
y:0,
宽度:500,
身高:300)
让sceneView=SCNView(帧:帧)
sceneView.showsStatistics=true
sceneView.autoenablesDefaultLighting=true
sceneView.allowsCameraControl=true
sceneView.scene=SCNScene()
//将视图设置到场景中
让cameraNode=SCNNode()
cameraNode.camera=SCNCamera()
cameraNode.position=SCInvector3(x:0,y:0,z:3)
场景视图,场景!。rootNode.addChildNode(cameraNode)
//将平面添加到场景中
让平面=SCN节点(几何图形:SCN平面(宽度:3,高度:3))
平面。几何?第一材料!。漫反射.contents=UIColor.red.带AlphaComponent(0.5)
平面.geometry?.firstMaterial?.IsDoubleside=真
场景视图,场景!。rootNode.addChildNode(平面)
/*
normalSource=[SCNGeometrySource GEOMETRYSOURCE WITHDATA:data
语义:scngemetrysourcesemanticnormal
向量计数:顶点计数
浮动组件:是的
组件制造商:3//nx,ny,nz
bytesPerComponent:sizeof(浮点)
数据偏移量:偏移量(MyVertex,nx)
数据列:sizeof(MyVertex)];
*/
让dataBuffer=plane.geometry?.sources(用于:SCNGeometrySource.Semantic.normal)[0]。数据
让colorArray=[UIColor.red,UIColor.orange,UIColor.yellow,UIColor.green,UIColor.blue,UIColor.systemIndigo,UIColor.purple,UIColor.brown,UIColor.black,UIColor.systemPink]
让scenegegeometrysource=dataBuffer!。不安全字节{
(vertexBuffer:UnsafePointer)->中的SCNGeometrySource
让sceneVectors=Array(UnsafeBufferPointer(开始:vertexBuffer,计数:dataBuffer!.count/MemoryLayout.stride))
变量i=0
对于SceneVector中的向量{
让气缸=SCN气缸(半径:0.05,高度:3)
cyl.firstMaterial!.diffuse.contents=colorArray[i]。带AlphaComponent(0.8)
设lineNode=SCNNode(几何图形:圆柱体)
lineNode.eulerAngles=向量
sceneView.scene!.rootNode.addChildNode(lineNode)
}
返回SCNGeometrySource(顶点:sceneVectors)
}
PlaygroundSupport.PlaygroundPage.current.liveView=sceneView

在“计算三角形法线”的苹果文档中,您可以找到解决方案。您只需要3个不在一条线上的点,然后使用此点:

以下代码定义三角形的三个顶点:

设顶点1=simd_float3(-1.5,0.5,0) 设顶点2=simd_float3(1,0,3) 设顶点3=simd_float3(0.5,-0.5,-1.5) 计算三角形法线的第一步是创建两个向量,这两个向量由表示三角形两侧的顶点之间的差值定义:

设vector1=顶点2-顶点3 设vector2=vertex2-vertex1 simd_交叉函数返回与传递的两个向量垂直的向量。在本例中,返回的向量是三角形的法线。因为法线表示一个方向,所以可以规格化该值以获得单位向量:

让normal=simd_归一化(simd_交叉(向量1,向量2))

//: 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