本文介绍了两点之间的 SceneKit 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定 2 个 3D 点(ab)和一个 SCNCapsule、SCNTorus、SCNTube 等,如何定位对象,使对象从a点开始并在b点结束?

Given 2 points in 3D (a,b) and an SCNCapsule, SCNTorus, SCNTube etc.,how to go about to position the object, so that the object starts at point a and ends at point b?

Swift 或 Objective-C 中的代码示例将不胜感激.

Code example in Swift or Objective-C would be appreciated.

根据 Moustachs 的回答,我设法做了一个二维解决方案:

From Moustachs answer I managed to do a 2-dimension solution:

var v1 = SCNVector3(x: Float(a.x), y: Float(a.y), z: 0.0)
var v2 = SCNVector3(x: Float(b.x), y: Float(b.y), z: 0.0)

let height = CGFloat(v1.distance(v2))
var capsule = SCNCapsule(capRadius: 0.1, height: height)

var node = SCNNode(geometry: capsule)

var midpoint = (v1 + v2) / 2.0

node.position = midpoint

var rotp = v2 - midpoint

let rotx = atan2( rotp.y, rotp.x )
node.eulerAngles = SCNVector3Make(0.0, 0.0, rotx)

self.addChildNode(node)

我知道,对于完整的 3D 旋转有无数种解决方案,但我不关心第三轴.尽管如此,似乎即使是第二个轴旋转也不适合我.也许我的数学让我望而却步.谁能告诉我如何将这段代码提升到 3D 空间?

I know, that there are infinite many solutions for a complete 3D rotation, but I do not care about the third axis. Still, it seems that even the second axis rotation will not work for me. Maybe my math eludes me. Anyone can tell me how to get this code lifted up to 3D space?

(我使用 Swift 和 Kim Pedersens SCNVector3Extensions:https://github.com/devindazzle/SCNVector3Extensions)

(I am using Swift and Kim Pedersens SCNVector3Extensions: https://github.com/devindazzle/SCNVector3Extensions)

推荐答案

我有好消息要告诉你!您可以链接两个点并在此 Vector 上放置一个 SCNNode !

I've good news for you ! You can link two points and put a SCNNode on this Vector !

拿着这个,享受在两点之间画线的乐趣!

Take this and enjoy drawing line between two points !

class   CylinderLine: SCNNode
{
    init( parent: SCNNode,//Needed to line to your scene
        v1: SCNVector3,//Source
        v2: SCNVector3,//Destination
        radius: CGFloat,// Radius of the cylinder
        radSegmentCount: Int, // Number of faces of the cylinder
        color: UIColor )// Color of the cylinder
    {
        super.init()

        //Calcul the height of our line
        let  height = v1.distance(v2)

        //set position to v1 coordonate
        position = v1

        //Create the second node to draw direction vector
        let nodeV2 = SCNNode()

        //define his position
        nodeV2.position = v2
        //add it to parent
        parent.addChildNode(nodeV2)

        //Align Z axis
        let zAlign = SCNNode()
        zAlign.eulerAngles.x = CGFloat(M_PI_2)

        //create our cylinder
        let cyl = SCNCylinder(radius: radius, height: CGFloat(height))
        cyl.radialSegmentCount = radSegmentCount
        cyl.firstMaterial?.diffuse.contents = color

        //Create node with cylinder
        let nodeCyl = SCNNode(geometry: cyl )
        nodeCyl.position.y = CGFloat(-height/2)
        zAlign.addChildNode(nodeCyl)

        //Add it to child
        addChildNode(zAlign)

        //set constraint direction to our vector
        constraints = [SCNLookAtConstraint(target: nodeV2)]
    }

    override init() {
        super.init()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

private extension SCNVector3{
    func distance(receiver:SCNVector3) -> Float{
        let xd = receiver.x - self.x
        let yd = receiver.y - self.y
        let zd = receiver.z - self.z
        let distance = Float(sqrt(xd * xd + yd * yd + zd * zd))

        if (distance < 0){
            return (distance * -1)
        } else {
            return (distance)
        }
    }
}

这篇关于两点之间的 SceneKit 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 08:44