Water forms a simple molecular structure which we will build in AR with Apple’s . We’ll learn basics of like working with nodes and manipulating them. ARKit ARKit Start a new AR project in XCode with as content SceneKit technology Build and Run to make sure everything is fine — You should be able to see the default spaceship Now, delete the following lines of spaceship which is not needed // Create a new scenelet scene = SCNScene(named: "art.scnassets/ship.scn")!// Set the scene to the viewsceneView.scene = scene For reference, the x, y and z axes are as below. The camera is at the origin. Oxygen is bigger than Hydrogen. So, we’ll first place an Oxygen atom. We’ll work with the from now on. ViewController.swift Add an anchor for the oxygen. func getMainAnchor() -> ARAnchor { // Creates an anchor at a distance 0.1m in front of you . var anchorPosition = matrix\_identity\_float4x4 anchorPosition.columns.3.z = -0.1 let mainAnchor = ARAnchor(transform: anchorPosition) return mainAnchor } Add the following code to function. viewDidLoad let sphere = SCNSphere(radius: 0.01) let oxygenNode = SCNNode(geometry: sphere) oxygenNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red sceneView.session.add(anchor: self.getMainAnchor()) sceneView.scene.rootNode.addChildNode(oxygenNode) oxygenNode.position = SCNVector3(0.0, 0.0, Float(-0.1)) The above code creates a sphere geometry and an SCNNode for the Oxygen atom. Then, add the AR Anchor to the sceneView’s session and then add the Oxygen atom node as a child to the sceneview’s root node. This puts a red sphere at 0.1m in front of you. Fig 1. Oxygen Atom Now we should think about how we are going to construct the molecule by analyzing the structure. Fig 2. Top view of the molecule From the structure we have here, we need three atoms(spheres) and two tubes/cylinders which are separated by the specified angle. Also, the axis of the tubes need to be in X-Z plane(axis of the tube here means an imaginary line passing through the center of the tube length wise). Now this can be done in multiple ways by various translations and rotations. I will pick the one which is relatively easy. Place the Oxygen atom first Add a tube/cylinder(bond) which at first is pointing in +Y direction Fig 3. Tube(O-H bond) on top of Oxygen 3. Now rotate the tube 90º along Z axis to place the tube in X-Z axis Fig 4. OH bond rotated by 90 degrees 4. Rotate again by specified angle to form the water molecule. Do this for other O-H bond too Fig 5. OH bond rotated by 37.775 degrees along Y axis 5. Add the Hydrogen atoms and you have the water molecule. Now lets put this into code… The following code adds two tubes at the head of the Oxygen atom already in place as shown in Fig 3. By default the pivot of the tube is at the center. We change that and place it at the lower end of the tube. let tube = SCNTube(innerRadius: 0.001, outerRadius: 0.0015, height: 0.05) let OHbondOne = SCNNode(geometry: tube)OHbondOne.geometry?.firstMaterial?.diffuse.contents = UIColor.blue let OHbondTwo = SCNNode(geometry: tube)OHbondTwo.geometry?.firstMaterial?.diffuse.contents = UIColor.blue OHbondOne.position = SCNVector3(0.0, 0.025, -0.1)OHbondOne.pivot = SCNMatrix4MakeTranslation(0, -0.025, 0)OHbondOne.position.y = OHbondOne.position.y - 0.025 OHbondTwo.position = SCNVector3(0.0, 0.025, -0.1)OHbondTwo.pivot = SCNMatrix4MakeTranslation(0, -0.025, 0)OHbondTwo.position.y = OHbondTwo.position.y - 0.025 sceneView.scene.rootNode.addChildNode(OHbondOne)sceneView.scene.rootNode.addChildNode(OHbondTwo) Now we need to rotate the tubes 90º clockwise to bring them in X-Z axis as in Fig 4. let rotateAlongZAxis = SCNAction.rotateBy(x:0 , y: 0, z: -CGFloat(Float.pi/2), duration: 1) OHbondOne.runAction(rotateAlongZAxis)OHbondTwo.runAction(rotateAlongZAxis) Now we need to rotate the tubes along Y axis to get the molecular structure (Fig 5). But we need to determine to what angle it needs to be rotated. Simple analysis of the angles gives us the following. We need to rotate first tube by 37.755º and second tube by 142.205º(37.755º+104.45º). let rotateOHBondOneAlongYAxis = SCNAction.rotateBy(x:CGFloat(self.degreesToRadians(degrees: 37.755)), y: 0, z: 0, duration: 0.1) let rotateOHBondTwoAlongYAxis = SCNAction.rotateBy(x:CGFloat(self.degreesToRadians(degrees: 142.205)), y: 0, z: 0, duration: 0.1) OHbondOne.runAction(rotateOHBondOneAlongYAxis) OHbondTwo.runAction(rotateOHBondTwoAlongYAxis) Function to convert degrees to radians func degreesToRadians(degrees: Float) -> Float {return (degrees * .pi) / 180.0} Fig 6. OH bonds after rotation along Y axis Now we need to add the Hydrogen atoms. We know where to add — at the other end of the bonds. But the problem is how exactly do we do it? Fig 7. Hydrogen atom displacement calculation So for H1, Place the Hydrogen atom in the same place as Oxygen and then move ‘b’ distance in -X direction ( To place the node on left side of Oxygen) move ‘a’ distance in -Z direction and for H2, Place the Hydrogen atom in the same place of Oxygen and then move ‘b’ distance in +X direction ( To place the node on right side of Oxygen) move ‘a’ distance in -Z direction Here is the code to do that, Create Hydrogen nodes let hSphere = SCNSphere(radius: 0.007) let hOneNode = SCNNode(geometry: hSphere)hOneNode.geometry?.firstMaterial?.diffuse.contents = UIColor.gray let hTwoNode = SCNNode(geometry: hSphere)hTwoNode.geometry?.firstMaterial?.diffuse.contents = UIColor.gray hOneNode.position = SCNVector3(0.0, 0.0, Float(-0.1))hTwoNode.position = SCNVector3(0.0, 0.0, Float(-0.1)) sceneView.scene.rootNode.addChildNode(hOneNode)sceneView.scene.rootNode.addChildNode(hTwoNode) self.placeHOneAtom(hone: hOneNode)self.placeHTwoAtom(htwo: hTwoNode) The two functions to perform the x and z displacements mentioned in Fig. 7 // 0.05m is the bond(tube) length here func placeHOneAtom(hone: SCNNode) { hone.position.x = hone.position.x -cos(self.degreesToRadians(degrees: 37.755)) \* 0.05 hone.position.z = hone.position.z + sin(self.degreesToRadians(degrees: 37.755)) \* 0.05 } func placeHTwoAtom(htwo: SCNNode) { htwo.position.x = htwo.position.x + cos(self.degreesToRadians(degrees: 37.755)) \* 0.05 htwo.position.z = htwo.position.z + sin(self.degreesToRadians(degrees: 37.755)) \* 0.05 } Finally, we have the molecule once all of the code is added… The completed project is available . here Note: Instead of changing the pivot of the tubes and rotating them, one could just rotate them along Z & Y axes as we did and then do the displacements along X and Z axes similar to the Hydrogen atoms. That will also give the same effect.