1

I'm experimenting with SpriteKit and ARKit and wondering how can I calculate the angle(s) between two ARAnchors in the same scene.

This means getting the position of the anchors on the world and calculate the angle of the line that they define to the horizontal plane (or another arbitrary plane).

Thanks

João Colaço
  • 1,202
  • 1
  • 14
  • 38
  • 3
    Possible duplicate of [Angle between 2 Lines in 3D](https://stackoverflow.com/questions/46790176/angle-between-2-lines-in-3d) – Knight0fDragon Nov 07 '17 at 14:45

1 Answers1

1

First we need to get world position for both anchors. These coordinates can be retrieved from each anchor transform like this:

let transform = anchor.transform
let position = vector_float3.init(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)

Now we can have two points in space, for each anchor. Lets call them p1 and p2. To calculate the angle to the horizontal we need a third point.

If the vertice of our angle is p1 this new point will have the same y coordinate as p1 but right below or above p2. So:

let p2Hor = vector_float3.init(p2.x, p1.y, p2.z)

To calculate the angle we need the normalised vectors from the vertice (p1) to each of the points (p2 and p2Hor) and their dot product. Those operations with vector_float3 and the simd module are rather easy. The normalised vectors are calculated like this:

let p1ToP2Norm = normalize(p2 - p1)
let p1ToP2HorNorm = normalize(p2Hor - p1)

And the dot product:

let dotProduct = dot(p1ToP2Norm, p1ToP2HorNorm)

The angle (in radians) is:

let angle = acos(dotProduct)

All of this in an extension for vector_float3 in swift for ARKit:

import ARKit
import simd


extension vector_float3 {

    /// Returns the angle of a line defined by to points to a horizontal plane
    ///
    /// - Parameters:
    ///   - p1: p1 (vertice)
    ///   - p2: p2
    /// - Returns: angle to a horizontal crossing p1 in radians
    static func angleBetweenPointsToHorizontalPlane(p1:vector_float3, p2:vector_float3) -> Float {

        ///Point in 3d space on the same level of p1 but equal to p2
        let p2Hor = vector_float3.init(p2.x, p1.y, p2.z)

        let p1ToP2Norm = normalize(p2 - p1)
        let p1ToP2HorNorm = normalize(p2Hor - p1)

        let dotProduct = dot(p1ToP2Norm, p1ToP2HorNorm)

        let angle = acos(dotProduct)

        return angle
    }
}
João Colaço
  • 1,202
  • 1
  • 14
  • 38