我有2个SCNSphere,我想用SCNCylinder“链接”它们(类似于这个O< - > O)但我无法实现它我尝试使用SCNNode pivot属性应用旋转,lookAt(_ :)但是没有一个能让我实现我想要的目标。
作为约束,出于架构原因,我希望圆柱体是第一个球体的子元素。
假设我们有一个简单的情况,第一个和第二个球体的半径为0.1,并且没有对它们应用旋转,只有位置是相关的:
static func createSphere(position: SCNVector3, color: UIColor = .red) -> SCNNode {
let shape = SCNSphere(radius: 0.1)
shape.firstMaterial?.diffuse.contents = color
let node = SCNNode(geometry: shape)
node.position = position
return node
}
创建“链接节点”:
static func createCylinder(position: SCNVector3, color: UIColor = .green) -> SCNNode {
let shape = SCNCylinder(radius: 0.2, height: 1.0)
shape.firstMaterial?.diffuse.contents = color
let node = SCNNode(geometry: shape)
node.position = position
return node
}
所有人都这样使用:
/// Create a sphere and the related link if there is a next sphere
static func createPOI(position: SCNVector3, nextPosition: SCNVector3? = nil) -> SCNNode {
var node: SCNNode = createSphere(position: position, color: .black)
if let nextPosition = nextPosition {
let lineNode = createLine(position: SCNVector3.zero, targetPosition: nextPosition)
node.addChildNode(lineNode)
}
return node
}
static func createLine(position: SCNVector3, targetPosition: SCNVector3) -> SCNNode {
let node = createCylinder(position: position)
//step 1: handle rotation
node.position = position
//node.look(at: targetPosition)
node.eulerAngles.x = Float.pi/2
node.eulerAngles.y = atan2f(targetPosition.y, targetPosition.magnitude)
//step 2: handle scaling and positioning
node.pivot = SCNMatrix4MakeTranslation(-0.5, 0, 0)
let width = CGFloat((targetPosition - position).magnitude)
(node.geometry as? SCNCylinder)?.height = width
//TODO: Cylinder should link source and target nodes
//Tried a lot of things above but didn't manage to do it
return node
}