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 poin
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)
}
}
}
There is no easy way to do it, but it should not be that hard either. You should implement an algorithm that go through the following steps:
SCNVector3
d
is the previously found distance).
SCNCapsule
and SCNTube
, set height
to the distance SCNTorus
, set ringRadius
to d/2-pipeRadius
SCNBox
, set any side to d
Once you do that, the shape you created should meet the points at both ends. You can check this is correct using a bounding box, making sure the right axis is equal to the distance.
I have no code sample, but give it a try and if it doesn't work I can debug it for you.