Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Water forms a simple molecular structure which we will build in AR with Apple’s ARKit. We’ll learn basics of ARKit like working with nodes and manipulating them.
- Start a new AR project in XCode with SceneKit as content 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 scene let scene = SCNScene(named: "art.scnassets/ship.scn")!// Set the scene to the view sceneView.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 ViewController.swift from now on.
- 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 viewDidLoadfunction.
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.
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.
Let’s build a water molecule with ARKit was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.