9

I have a simple Swift ARKit setup where I have a SCNNode with a 3D object that is visible in an ARSCNView.

I want to determine the 2D coordinates of this object on the ARSCNView. By this I mean the x- and y-coordinates the object has when it is drawn onto the screen.

I have provided a sketch to illustrate what I mean: Sketch

Is there a way to get these coordinates, or at least an approximation? I need this in order to do some further processing with the camera frame. Basically I am interested in the area the object occupies on the screen.

AscendingEagle
  • 771
  • 1
  • 7
  • 17

1 Answers1

10

You can use SCNSceneRenderer projectPoint:point :

Projects a point from the 3D world coordinate system of the scene to the 2D pixel coordinate system of the renderer.

let node:SCNNode = // Your node
let nodeWorldPosition = node.position
let nodePositionOnScreen = renderer.projectPoint(nodeWorldPosition)
let x = nodePositionOnScreen.x
let y = nodePositionOnScreen.y

Note : A point projected from the near (resp. far) clip plane will have a z component of 0 (resp. 1).


The same method can be used with ARAnchor :

let anchor:ARAnchor = // ...
let anchorWorldPosition = SCNVector3(anchor.transform.columns.3)
let anchorPositionOnScreen = renderer.projectPoint(anchorWorldPosition)
let x = anchorPositionOnScreen.x
let y = anchorPositionOnScreen.y
Axel Guilmin
  • 11,454
  • 9
  • 54
  • 64
  • Is there a way to make it work with ARImageAnchor ? – Scalpweb Jul 01 '19 at 15:52
  • `ARImageAnchor` is a subclass of `ARAnchor` so I think it should work the same, I did not test it though – Axel Guilmin Jul 02 '19 at 08:32
  • Reference to member 'projectPoint' cannot be resolved without a contextual type – Ahmadreza Dec 04 '21 at 19:10
  • 1
    Note that `ARSCNView` conforms to `SCNSceneRenderer` protocol, so you can use `projectPoint:point:` method directly with your reference to `ARSCNView`. This was not readily obvious to me as someone new to SceneKit. – markckim Jun 19 '22 at 05:30
  • this line: let nodeWorldPosition = node.position should be: let nodeWorldPosition = node.worldPosition – us_david Oct 14 '22 at 16:16