ez4nick
ez4nick

Reputation: 10209

Align SCNText Along SCNCylinder

I am just starting out with ARKit and trying to make a very simple app where the user selects 2 points shown as SCNSphere, a "line" (SCNCylinder) connects the 2 spheres and some text SCNText will appear to show the distance between the 2 points. The issue is I would like for the text to be aligned such that it is parallel to the cylinder and oriented "up".

This is my code of how I have the cylinder setup:

        let lineBetweenPoints = SCNCylinder(radius: 0.005, height: CGFloat(distance_global))
        
        
        let dotMaterial2 = SCNMaterial()
        dotMaterial2.diffuse.contents = UIColor.orange
        
        lineBetweenPoints.materials = [dotMaterial2]

        lineNode.position = SCNVector3(x: (dotNodes[0].position.x + dotNodes[1].position.x) / 2,
                                               y: (dotNodes[0].position.y + dotNodes[1].position.y) / 2,
                                               z: (dotNodes[0].position.z + dotNodes[1].position.z) / 2)

        let from = dotNodes[0].position
        let to   = dotNodes[1].position
        
        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 distanceForCalc =  sqrtf( (x2-x1) * (x2-x1) +
                               (y2-y1) * (y2-y1) +
                               (z2-z1) * (z2-z1) )
        
        pitch   = Float.pi / 2
        yaw     = acos((to.z-from.z)/distanceForCalc)
        roll    = atan2((to.y-from.y),(to.x-from.x))

        lineNode.eulerAngles = SCNVector3(pitch, yaw, roll)
        sceneView.scene.rootNode.addChildNode(lineNode)

This works perfectly for the cylinder, it goes through the 2 points (dotNodes[0] and dotNodes[1] and it is oriented appropriately based on how the user has selected the points.

Now, for the SCNText this is what I tried:

let text = SCNText(string: text, extrusionDepth: 0.5)
text.firstMaterial?.diffuse.contents = UIColor.blue
textNode = SCNNode(geometry: text)
textNode.position = SCNVector3(x: (dotNodes[0].position.x + dotNodes[1].position.x) / 2,
                                                   y: (dotNodes[0].position.y + dotNodes[1].position.y) / 2,
                                                   z: (dotNodes[0].position.z + dotNodes[1].position.z) / 2)

textNode.eulerAngles = SCNVector3(pitch, yaw, roll)

textNode.scale = SCNVector3(0.005, 0.005, 0.005)
    
sceneView.scene.rootNode.addChildNode(textNode)

When this runs the position of the text is correct, but the orientation is not. I think I am confused why applying the same .eulerAngles to both the SCNCylinder and SCNText do not produce the same resultls.

I will also add that I did some testing myself with manually adjusting the pitch, yaw, and roll just to see what the correct values should be and this is what I came up with for 2 different orientations.

Calculated: yaw: 2.1229775, pitch: 1.5707963, roll: -1.6493037

"Correct": yaw: -0.027021624, pitch: 0.2207966, roll: -1.6493037


Calculated: yaw: 1.0765738, pitch: 1.5707963, roll: -0.13361251

"Correct": yaw: -0.27342623, pitch: -0.1292034, roll: -0.18361253

But unfortunately that did not lead me anywhere either as there is no immediately obvious pattern from that.

Upvotes: 2

Views: 59

Answers (0)

Related Questions