# Programmatically set camera position

**URL:** <https://discourse.slicer.org/t/programmatically-set-camera-position/8301>\
**Category:** Development\
**Created:** [September 4, 2019, 7:11pm UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301 "2019-09-04T19:11:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)\
**Post date:** [September 4, 2019, 7:11pm UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/1 "2019-09-04T19:11:20Z")

</div>

Hi,

I want to set camera position programmatically in this way:

```auto
int wasModifying = camera->StartModify();
camera->SetPosition(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
camera->SetFocalPoint(cameraFocalPointPosition[0], cameraFocalPointPosition[1], cameraFocalPointPosition[2]);
camera->SetViewUp(0, 0, 1);
camera->EndModify(wasModifying);

```

which works in some cases. However, when I zoom in or out before the calls manually so that the camera position is significantly different than the position I want to set, the view stays black after the calls. Only when I start to rotate the view afterwards manually, it gets updated and shows the correct angle. Is there any way to force an update?

Thanks

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [September 4, 2019, 8:05pm UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/2 "2019-09-04T20:05:38Z")

</div>

ViewUp vector must be orthogonal to the line that connects position and focal point. Otherwise the behavior is undefined.

---

<div class="post-metadata">

**Author:** ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)\
**Post date:** [September 5, 2019, 8:30am UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/3 "2019-09-05T08:30:45Z")

</div>

Thanks for your input, however it did not solve the problem. The missing thing was to call `ResetClippingRange`. The code below does what it should.

```auto
viewLogic->StartCameraNodeInteraction(vtkMRMLCameraNode::LookFromAxis);
camera->SetFocalPoint(cameraFocalPointPosition[0], cameraFocalPointPosition[1], cameraFocalPointPosition[2]);
camera->SetPosition(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
camera->SetViewUp(0, 0, 1);
camera->GetCamera()->OrthogonalizeViewUp();
camera->ResetClippingRange();
viewLogic->EndCameraNodeInteraction();

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [September 5, 2019, 1:25pm UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/4 "2019-09-05T13:25:28Z")

</div>

Yes, `ResetClippingRange` is a good point, you need that.

`OrthogonalizeViewUp` discards current camera ViewUp vector value. So, if you care what is up direction in the view then you need to set ViewUp properly (and don’t call `OrthogonalizeViewUp`); if it does not matter which way is up in the view then just call `OrthogonalizeViewUp` (and don’t call `SetViewUp`). See details in [vtkCamera source code](https://github.com/Kitware/VTK/blob/master/Rendering/Core/vtkCamera.cxx).

---

<div class="post-metadata">

**Author:** ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)\
**Post date:** [September 6, 2019, 8:31am UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/5 "2019-09-06T08:31:44Z")

</div>

The camera automatically orthogonalizes any given ViewUp vector.  
See [VTK User’s Guide](https://vtk.org/vtk-users-guide/) (page 50):

 ![vtk](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/4/543591a869409c09154ef6c62d249e2ce17ae04a.png)  
and

> <https://github.com/Kitware/VTK/blob/ad16439a2f12c41d9de73a72b211bf775d713963/Common/Transforms/vtkPerspectiveTransform.cxx#L440-L443>

This is called by `setViewUp(...) -> ComputeViewTransform() -> Transform->SetupCamera(...)`

The call to `OrthogonalizeViewUp()` is required to retrieve back the orthogonalized vector from the transform for retrieving it via `GetViewUp()` and for the convenience methods like `Pitch, Roll, Yaw, ...`

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [September 6, 2019, 2:28pm UTC](https://discourse.slicer.org/t/programmatically-set-camera-position/8301/6 "2019-09-06T14:28:11Z")

</div>

> [@rprueckl](#):
>
> The camera automatically orthogonalizes any given ViewUp vector.

That’s correct. That’s why you don’t need to call both `SetViewUp()` and `OrthogonalizeViewUp()`.

Note that the built-in very simplistic orthogonalization method should only be used for small angular deviations. If view up direction is nearly parallel to the view normal then the result is undefined.

In the cited VTK User guide example the OrthogonalizeViewUp call is unnecessary, but since the user guide is not maintained anymore, we cannot submit a PR to fix it. VTK textbook is still maintained, you can find up-to-date version [here](https://lorensen.github.io/VTKExamples/site/VTKBook/).
