# ArcballCamera has wrong rotation if target is not \[0, 0, 0\]

**URL:** <https://forums.kodeco.com/t/arcballcamera-has-wrong-rotation-if-target-is-not-0-0-0/179283>\
**Category:** Metal by Tutorials\
**Created:** [September 30, 2022, 9:41pm UTC](https://forums.kodeco.com/t/arcballcamera-has-wrong-rotation-if-target-is-not-0-0-0/179283 "2022-09-30T21:41:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mk2019](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/mk2019/32/108824_2.png) [@mk2019](https://forums.kodeco.com/u/mk2019)\
**Post date:** [September 30, 2022, 9:41pm UTC](https://forums.kodeco.com/t/arcballcamera-has-wrong-rotation-if-target-is-not-0-0-0/179283/1 "2022-09-30T21:41:33Z")

</div>

Hi @caroline , please see the attached project and video.

[https://dl.dropboxusercontent.com/s/lm3rltw8y5i1cyg/ArcballCamera.mov?dl=0](https://dl.dropboxusercontent.com/s/lm3rltw8y5i1cyg/ArcballCamera.mov?dl=0)

[05-lighting-fundamentals.zip](https://forums.kodeco.com/uploads/short-url/uWMagZ5ib6NGiGINHSSGVozqJnl.zip) (163.1 KB)

I set train.position = [10, 0, 0], and camera.target = [10, 0, 0].  
So in my opinion the camera should rotate around the train when moved, but as you can see in the movie it is rotating around in a bizarre way.

thx

---

<div class="post-metadata">

**Author:** ![caroline](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/caroline/32/111867_2.png) [@caroline](https://forums.kodeco.com/u/caroline)\
**Post date:** [October 1, 2022, 12:05pm UTC](https://forums.kodeco.com/t/arcballcamera-has-wrong-rotation-if-target-is-not-0-0-0/179283/2 "2022-10-01T12:05:02Z")

</div>

Yes, you’re right. The `Arcball` camera doesn’t work correctly.

Try this code for `Arcball`:

```auto
class ArcballCamera: Camera {

  var fov = Float(70).degreesToRadians

  let minDistance: Float = 0.0
  let maxDistance: Float = 20
  var target: float3 = [0, 0, 0]
  var distance: Float = 2.5

  override var viewMatrix: float4x4 {
    let matrix: float4x4
    if target == position {
      matrix = (float4x4(translation: target) * float4x4(rotationYXZ: rotation)).inverse
    } else {
      matrix = float4x4(eye: position, center: target, up: [0, 1, 0])
    }
    return matrix
  }

  override func zoom(delta: Float) {
    let sensitivity: Float = 0.05
    distance -= delta * sensitivity
    let rotateMatrix = float4x4(
      rotationYXZ: [-rotation.x, rotation.y, 0])
    let distanceVector = float4(0, 0, -distance, 0)
    let rotatedVector = rotateMatrix * distanceVector
    position = target + rotatedVector.xyz
  }

  override func rotate(delta: float2) {
    let sensitivity: Float = 0.005
    rotation.y += delta.x * sensitivity
    rotation.x += delta.y * sensitivity
    rotation.x = max(
      -Float.pi/2,
      min(rotation.x, Float.pi/2))

    let rotateMatrix = float4x4(
      rotationYXZ: [-rotation.x, rotation.y, 0])
    let distanceVector = float4(0, 0, -distance, 0)
    let rotatedVector = rotateMatrix * distanceVector
    position = target + rotatedVector.xyz
  }
}

```

This one rotates the vector properly and takes into account `distance`. It’s not completely correct, as it does a weird flip at extremes, but you can probably put limits on the rotation to prevent that.

In `Renderer`, when you initialise `camera`, after setting `camera.rotation.x = Float(-10).degreesToRadians`, add this:

```auto
 camera.rotate(delta: [0, 0])

```

This just initializes the view matrix.
