如何在 SceneKit 中的两点之间画一条线? [英] How to draw a line between two points in SceneKit?

查看:45
本文介绍了如何在 SceneKit 中的两点之间画一条线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在 SceneKit 中有两个点(例如 (1,2,3)(-1,-1,-1)).我如何在两者之间划一条线?

我看到有一个 SCNBox 对象我可以使用,但它只允许我指定中心(例如通过 simdPosition).修改它的其他方法是变换(我不知道如何使用)或欧拉角(我不确定如何计算需要使用的角度).

解决方案

您可以使用以下方法在两点之间画一条线:

import SceneKit扩展 SCNGeometry {class func line(vector1: SCNVector3,vector2: SCNVector3) ->SCNGeometry {让源 = SCNGeometrySource(vertices: [vector1,向量 2])让索引:[Int32] = [0,1]让元素 = SCNGeometryElement(索引:索引,原始类型:.line)返回 SCNGeometry(来源:[来源],元素:[元素])}}

...然后将其提供给 ViewController 中的 addLine 函数:

class ViewController: UIViewController {//一些代码...func addLine(开始:SCNVector3,结束:SCNVector3){让 lineGeo = SCNGeometry.line(vector1: start,向量2:结束)让 lineNode = SCNNode(geometry: lineGeo)sceneView.scene.rootNode.addChildNode(lineNode)}}

<块引用>

众所周知,线的宽度不能改变(因为没有属性可以改变),所以你可以使用圆柱原始几何体代替线:

extension SCNGeometry {类 func 圆柱线(来自:SCNVector3,至:SCNVector3,段:Int) ->SCN节点{让 x1 = from.x让 x2 = to.x让 y1 = from.y让 y2 = to.y让 z1 = from.z让 z2 = to.z让距离 = sqrtf( (x2-x1) * (x2-x1) +(y2-y1) * (y2-y1) +(z2-z1) * (z2-z1) )让圆柱体 = SCNCylinder(半径:0.005,高度:CGFloat(距离))圆柱体.radialSegmentCount = 段圆柱体.firstMaterial?.diffuse.contents = UIColor.green让 lineNode = SCNNode(几何:圆柱体)lineNode.position = SCNVector3(x: (from.x + to.x)/2,y: (from.y + to.y)/2,z: (from.z + to.z)/2)lineNode.eulerAngles = SCNVector3(Float.pi/2,acos((to.z-from.z)/距离),atan2((to.y-from.y),(to.x-from.x)))返回线节点}}

...然后以相同的方式将其提供给 ViewController:

class ViewController: UIViewController {//一些代码...func addLine(开始:SCNVector3,结束:SCNVector3){让圆柱线节点 = SCNGeometry.圆柱线(从:开始,到:结束,细分:3)sceneView.scene.rootNode.addChildNode(圆柱线节点)}}

If I have two points in SceneKit (e.g. (1,2,3) and (-1,-1,-1)). How do I draw a line between the two?

I see that there is a SCNBox object I may be able to use, but that only allows me to specify the center (e.g. via simdPosition). The other ways to modify it are the transform (which I don't know how to use), or the Euler angles (which I'm not sure how to calculate which ones I need to use).

解决方案

You can draw a line between two points using the following approach:

import SceneKit

extension SCNGeometry {

    class func line(vector1: SCNVector3,
                    vector2: SCNVector3) -> SCNGeometry {

        let sources = SCNGeometrySource(vertices: [vector1,
                                                   vector2])
        let index: [Int32] = [0,1]

        let elements = SCNGeometryElement(indices: index,
                                    primitiveType: .line)

        return SCNGeometry(sources: [sources],
                          elements: [elements])
    }
}

...and then feed it to addLine function in ViewController:

class ViewController: UIViewController { 

    // Some code...

    func addLine(start: SCNVector3, end: SCNVector3) {
        let lineGeo = SCNGeometry.line(vector1: start,
                                       vector2: end)
        let lineNode = SCNNode(geometry: lineGeo)
        sceneView.scene.rootNode.addChildNode(lineNode)
    }
}

As we all know line's width can't be changed (cause there's no property to do it), so you can use cylinder primitive geometry instead of a line:

extension SCNGeometry {

    class func cylinderLine(from: SCNVector3, 
                              to: SCNVector3,
                        segments: Int) -> SCNNode {

        let x1 = from.x
        let x2 = to.x

        let y1 = from.y
        let y2 = to.y

        let z1 = from.z
        let z2 = to.z

        let distance =  sqrtf( (x2-x1) * (x2-x1) +
                               (y2-y1) * (y2-y1) +
                               (z2-z1) * (z2-z1) )

        let cylinder = SCNCylinder(radius: 0.005,
                                   height: CGFloat(distance))

        cylinder.radialSegmentCount = segments

        cylinder.firstMaterial?.diffuse.contents = UIColor.green

        let lineNode = SCNNode(geometry: cylinder)

        lineNode.position = SCNVector3(x: (from.x + to.x) / 2,
                                       y: (from.y + to.y) / 2,
                                       z: (from.z + to.z) / 2)

        lineNode.eulerAngles = SCNVector3(Float.pi / 2,
                                          acos((to.z-from.z)/distance),
                                          atan2((to.y-from.y),(to.x-from.x)))

        return lineNode
    }
}

...then feed it the same way to ViewController:

class ViewController: UIViewController { 

    // Some code...

    func addLine(start: SCNVector3, end: SCNVector3) {

        let cylinderLineNode = SCNGeometry.cylinderLine(from: start, 
                                                          to: end, 
                                                    segments: 3)

        sceneView.scene.rootNode.addChildNode(cylinderLineNode)
    }
}

这篇关于如何在 SceneKit 中的两点之间画一条线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆