# CameraModel2

VTKExamples/Cxx/Visualization/CameraModel2

### Description

This example illustrates the camera movement centered at the camera position.

Note

For camera movement around the focal point see CameraModel1.

Note

This example corresponds to Figure 3-13 in the VTK Text.

Note

This is an adaptation of the code written by Chung Kai Lun Pete.

### Code

CameraModel2.cxx

    /*
       Adaptation of the code by
            Author: Chung Kai Lun Peter
            Email: hkpeterpeter@gmail.com
            File:
                demo_vtk_camera_2.cpp
            Purpose:
                    Ported from camera2.tcl.
                    It illustrates the camera model of VTK.
    */

    #include <vtkAppendPolyData.h>
    #include <vtkCellArray.h>
    #include <vtkConeSource.h>
    #include <vtkContourFilter.h>
    #include <vtkCubeSource.h>
    #include <vtkDataSetMapper.h>
    #include <vtkImplicitModeller.h>
    #include <vtkLODActor.h>
    #include <vtkPoints.h>
    #include <vtkPolyData.h>
    #include <vtkPolyDataMapper.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    #include <vtkRenderer.h>
    #include <vtkRotationalExtrusionFilter.h>
    #include <vtkSmartPointer.h>
    #include <vtkSphereSource.h>
    #include <vtkTextActor.h>
    #include <vtkTextProperty.h>
    #include <vtkTransform.h>
    #include <vtkTransformFilter.h>
    #include <vtkTransformPolyDataFilter.h>
    #include <vtkWarpTo.h>

    #include <vtkCamera.h>
    #include <vtkNamedColors.h>
    #include <vtkProperty.h>

    #include <algorithm>
    #include <array>

    int main(int /* argc */, char* /* argv */ [])
    {

      vtkSmartPointer<vtkNamedColors> colors =
        vtkSmartPointer<vtkNamedColors>::New();

      // Set the background color. Match those in VTKTextbook.pdf.
      auto SetColor = [&colors](std::array<double, 3>& v,
                                std::string const& colorName) {
        auto const scaleFactor = 255.0;
        std::transform(std::begin(v), std::end(v), std::begin(v),
                       [=](double const& n) { return n / scaleFactor; });
        colors->SetColor(colorName, v.data());
        return;
      };
      std::array<double, 3> azArrowColor{{255, 77, 77}};
      SetColor(azArrowColor, "AzimuthArrowColor");
      std::array<double, 3> elevArrowColor{{77, 255, 77}};
      SetColor(elevArrowColor, "ElevationArrowColor");
      std::array<double, 3> rollArrowColor{{255, 255, 77}};
      SetColor(rollArrowColor, "RollArrowColor");
      std::array<double, 3> spikeColor{{255, 77, 255}};
      SetColor(spikeColor, "SpikeColor");
      std::array<double, 3> upSpikeColor{{77, 255, 255}};
      SetColor(upSpikeColor, "UpSpikeColor");

      // create a camera model
      vtkSmartPointer<vtkConeSource> camCS = vtkSmartPointer<vtkConeSource>::New();
      camCS->SetHeight(1.5);
      camCS->SetResolution(12);
      camCS->SetRadius(0.4);

      vtkSmartPointer<vtkCubeSource> camCBS = vtkSmartPointer<vtkCubeSource>::New();
      camCBS->SetXLength(1.5);
      camCBS->SetZLength(0.8);
      camCBS->SetCenter(0.4, 0, 0);

      vtkSmartPointer<vtkAppendPolyData> camAPD =
        vtkSmartPointer<vtkAppendPolyData>::New();
      camAPD->AddInputConnection(camCBS->GetOutputPort());
      camAPD->AddInputConnection(camCS->GetOutputPort());

      vtkSmartPointer<vtkPolyDataMapper> camMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
      camMapper->SetInputConnection(camAPD->GetOutputPort());
      vtkSmartPointer<vtkLODActor> camActor = vtkSmartPointer<vtkLODActor>::New();
      camActor->SetMapper(camMapper);
      camActor->SetScale(2, 2, 2);

      // draw the arrows
      vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
      vtkSmartPointer<vtkCellArray> ca = vtkSmartPointer<vtkCellArray>::New();
      vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
      pts->InsertNextPoint(0, 1, 0);
      pts->InsertNextPoint(8, 1, 0);
      pts->InsertNextPoint(8, 2, 0);
      pts->InsertNextPoint(10, 0, 0);
      pts->InsertNextPoint(8, -2, 0);
      pts->InsertNextPoint(8, -1, 0);
      pts->InsertNextPoint(0, -1, 0);
      ca->InsertNextCell(7);
      ca->InsertCellPoint(0);
      ca->InsertCellPoint(1);
      ca->InsertCellPoint(2);
      ca->InsertCellPoint(3);
      ca->InsertCellPoint(4);
      ca->InsertCellPoint(5);
      ca->InsertCellPoint(6);
      pd->SetPoints(pts);
      pd->SetPolys(ca);

      vtkSmartPointer<vtkPolyData> pd2 = vtkSmartPointer<vtkPolyData>::New();
      vtkSmartPointer<vtkCellArray> ca2 = vtkSmartPointer<vtkCellArray>::New();
      vtkSmartPointer<vtkPoints> pts2 = vtkSmartPointer<vtkPoints>::New();
      pts2->InsertNextPoint(0, 1, 0);
      pts2->InsertNextPoint(8, 1, 0);
      pts2->InsertNextPoint(8, 2, 0);
      pts2->InsertNextPoint(10, 0.01, 0);
      ca2->InsertNextCell(4);
      ca2->InsertCellPoint(0);
      ca2->InsertCellPoint(1);
      ca2->InsertCellPoint(2);
      ca2->InsertCellPoint(3);
      pd2->SetPoints(pts2);
      pd2->SetLines(ca2);

      vtkSmartPointer<vtkImplicitModeller> arrowIM =
        vtkSmartPointer<vtkImplicitModeller>::New();
      arrowIM->SetInputData(pd);
      arrowIM->SetSampleDimensions(50, 20, 8);

      vtkSmartPointer<vtkContourFilter> arrowCF =
        vtkSmartPointer<vtkContourFilter>::New();
      arrowCF->SetInputConnection(arrowIM->GetOutputPort());
      arrowCF->SetValue(0, 0.2);

      vtkSmartPointer<vtkWarpTo> arrowWT = vtkSmartPointer<vtkWarpTo>::New();
      arrowWT->SetInputConnection(arrowCF->GetOutputPort());
      arrowWT->SetPosition(5, 0, 5);
      arrowWT->SetScaleFactor(0.85);
      arrowWT->AbsoluteOn();

      vtkSmartPointer<vtkTransform> arrowT = vtkSmartPointer<vtkTransform>::New();
      arrowT->RotateY(60);
      arrowT->Translate(-1.33198, 0, -1.479);
      arrowT->Scale(1, 0.5, 1);

      vtkSmartPointer<vtkTransformFilter> arrowTF =
        vtkSmartPointer<vtkTransformFilter>::New();
      arrowTF->SetInputConnection(arrowWT->GetOutputPort());
      arrowTF->SetTransform(arrowT);

      vtkSmartPointer<vtkDataSetMapper> arrowMapper =
        vtkSmartPointer<vtkDataSetMapper>::New();
      arrowMapper->SetInputConnection(arrowTF->GetOutputPort());
      arrowMapper->ScalarVisibilityOff();

      // draw the azimuth arrows
      vtkSmartPointer<vtkLODActor> a1Actor = vtkSmartPointer<vtkLODActor>::New();
      a1Actor->SetMapper(arrowMapper);
      a1Actor->SetPosition(-9, 0, -1);
      a1Actor->GetProperty()->SetColor(
        colors->GetColor3d("AzimuthArrowColor").GetData());
      a1Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a1Actor->GetProperty()->SetSpecular(0.3);
      a1Actor->GetProperty()->SetSpecularPower(20);
      a1Actor->GetProperty()->SetAmbient(0.2);
      a1Actor->GetProperty()->SetDiffuse(0.8);

      vtkSmartPointer<vtkLODActor> a2Actor = vtkSmartPointer<vtkLODActor>::New();
      a2Actor->SetMapper(arrowMapper);
      a2Actor->RotateX(180);
      a2Actor->SetPosition(-9, 0, 1);
      a2Actor->GetProperty()->SetColor(
        colors->GetColor3d("AzimuthArrowColor").GetData());
      a2Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a2Actor->GetProperty()->SetSpecular(0.3);
      a2Actor->GetProperty()->SetSpecularPower(20);
      a2Actor->GetProperty()->SetAmbient(0.2);
      a2Actor->GetProperty()->SetDiffuse(0.8);

      // draw the elevation arrows
      vtkSmartPointer<vtkLODActor> a3Actor = vtkSmartPointer<vtkLODActor>::New();
      a3Actor->SetMapper(arrowMapper);
      a3Actor->RotateX(-90);
      a3Actor->SetPosition(-9, -1, 0);
      a3Actor->GetProperty()->SetColor(
        colors->GetColor3d("ElevationArrowColor").GetData());
      a3Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a3Actor->GetProperty()->SetSpecular(0.3);
      a3Actor->GetProperty()->SetSpecularPower(20);
      a3Actor->GetProperty()->SetAmbient(0.2);
      a3Actor->GetProperty()->SetDiffuse(0.8);

      vtkSmartPointer<vtkLODActor> a4Actor = vtkSmartPointer<vtkLODActor>::New();
      a4Actor->SetMapper(arrowMapper);
      a4Actor->RotateX(90);
      a4Actor->SetPosition(-9, 1, 0);
      a4Actor->GetProperty()->SetColor(
        colors->GetColor3d("ElevationArrowColor").GetData());
      a4Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a4Actor->GetProperty()->SetSpecular(0.3);
      a4Actor->GetProperty()->SetSpecularPower(20);
      a4Actor->GetProperty()->SetAmbient(0.2);
      a4Actor->GetProperty()->SetDiffuse(0.8);

      // draw the DOP
      vtkSmartPointer<vtkTransform> arrowT2 = vtkSmartPointer<vtkTransform>::New();
      arrowT2->Scale(1, 0.6, 1);
      arrowT2->RotateY(90);

      vtkSmartPointer<vtkTransformPolyDataFilter> arrowTF2 =
        vtkSmartPointer<vtkTransformPolyDataFilter>::New();
      arrowTF2->SetInputData(pd2);
      arrowTF2->SetTransform(arrowT2);

      vtkSmartPointer<vtkRotationalExtrusionFilter> arrowREF =
        vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
      arrowREF->SetInputConnection(arrowTF2->GetOutputPort());
      arrowREF->CappingOff();
      arrowREF->SetResolution(30);

      vtkSmartPointer<vtkPolyDataMapper> spikeMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
      spikeMapper->SetInputConnection(arrowREF->GetOutputPort());

      vtkSmartPointer<vtkLODActor> a5Actor = vtkSmartPointer<vtkLODActor>::New();
      a5Actor->SetMapper(spikeMapper);
      a5Actor->SetScale(0.3, 0.3, 0.6);
      a5Actor->RotateY(-90);
      a5Actor->SetPosition(-8, 0, 0);
      a5Actor->GetProperty()->SetColor(colors->GetColor3d("SpikeColor").GetData());
      a5Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a5Actor->GetProperty()->SetSpecular(0.3);
      a5Actor->GetProperty()->SetAmbient(0.2);
      a5Actor->GetProperty()->SetDiffuse(0.8);
      a5Actor->GetProperty()->SetSpecularPower(20);

      vtkSmartPointer<vtkLODActor> a7Actor = vtkSmartPointer<vtkLODActor>::New();
      a7Actor->SetMapper(spikeMapper);
      a7Actor->SetScale(0.2, 0.2, 0.7);
      a7Actor->RotateZ(90);
      a7Actor->RotateY(-90);
      a7Actor->SetPosition(-9, 1, 0);
      a7Actor->GetProperty()->SetColor(
        colors->GetColor3d("UpSpikeColor").GetData());
      a7Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a7Actor->GetProperty()->SetSpecular(0.3);
      a7Actor->GetProperty()->SetAmbient(0.2);
      a7Actor->GetProperty()->SetDiffuse(0.8);
      a7Actor->GetProperty()->SetSpecularPower(20);

      // focal point
      vtkSmartPointer<vtkSphereSource> ss = vtkSmartPointer<vtkSphereSource>::New();
      ss->SetRadius(0.5);
      vtkSmartPointer<vtkPolyDataMapper> fpMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
      fpMapper->SetInputConnection(ss->GetOutputPort());
      vtkSmartPointer<vtkLODActor> fpActor = vtkSmartPointer<vtkLODActor>::New();
      fpActor->SetMapper(fpMapper);
      fpActor->SetPosition(-9, 0, 0);
      fpActor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      fpActor->GetProperty()->SetSpecular(0.3);
      fpActor->GetProperty()->SetAmbient(0.2);
      fpActor->GetProperty()->SetDiffuse(0.8);
      fpActor->GetProperty()->SetSpecularPower(20);

      // create the roll arrows
      vtkSmartPointer<vtkWarpTo> arrowWT2 = vtkSmartPointer<vtkWarpTo>::New();
      arrowWT2->SetInputConnection(arrowCF->GetOutputPort());
      arrowWT2->SetPosition(5, 0, 2.5);
      arrowWT2->SetScaleFactor(0.95);
      arrowWT2->AbsoluteOn();

      vtkSmartPointer<vtkTransform> arrowT3 = vtkSmartPointer<vtkTransform>::New();
      arrowT3->Translate(-2.50358, 0, -1.70408);
      arrowT3->Scale(0.5, 0.3, 1);

      vtkSmartPointer<vtkTransformFilter> arrowTF3 =
        vtkSmartPointer<vtkTransformFilter>::New();
      arrowTF3->SetInputConnection(arrowWT2->GetOutputPort());
      arrowTF3->SetTransform(arrowT3);

      vtkSmartPointer<vtkDataSetMapper> arrowMapper2 =
        vtkSmartPointer<vtkDataSetMapper>::New();
      arrowMapper2->SetInputConnection(arrowTF3->GetOutputPort());
      arrowMapper2->ScalarVisibilityOff();

      // draw the roll arrows
      vtkSmartPointer<vtkLODActor> a6Actor = vtkSmartPointer<vtkLODActor>::New();
      a6Actor->SetMapper(arrowMapper2);
      a6Actor->RotateZ(90);
      a6Actor->SetPosition(-4, 0, 0);
      a6Actor->SetScale(1.5, 1.5, 1.5);
      a6Actor->GetProperty()->SetColor(
        colors->GetColor3d("RollArrowColor").GetData());
      a6Actor->GetProperty()->SetSpecularColor(
        colors->GetColor3d("White").GetData());
      a6Actor->GetProperty()->SetSpecular(0.3);
      a6Actor->GetProperty()->SetSpecularPower(20);
      a6Actor->GetProperty()->SetAmbient(0.2);
      a6Actor->GetProperty()->SetDiffuse(0.8);

      // Create the RenderWindow, Renderer and both Actors
      //
      vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New();
      vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
      renWin->AddRenderer(ren1);
      vtkSmartPointer<vtkRenderWindowInteractor> iren =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
      iren->SetRenderWindow(renWin);

      // Add the actors to the renderer, set the background and size
      ren1->AddActor(camActor);
      ren1->AddActor(a1Actor);
      ren1->AddActor(a2Actor);
      ren1->AddActor(a3Actor);
      ren1->AddActor(a4Actor);
      ren1->AddActor(a5Actor);
      ren1->AddActor(a6Actor);
      ren1->AddActor(a7Actor);
      ren1->AddActor(fpActor);
      ren1->SetBackground(colors->GetColor3d("SlateGray").GetData());
      renWin->SetSize(640, 480);

      // render the image

      vtkCamera* cam1 = (ren1->GetActiveCamera());
      ren1->ResetCamera();
      cam1->Azimuth(150);
      cam1->Elevation(30);
      cam1->Dolly(1.5);
      ren1->ResetCameraClippingRange();

      // Create a TextActor for Yaw  (a1 and a2 actor's color)
      vtkSmartPointer<vtkTextActor> text = vtkSmartPointer<vtkTextActor>::New();
      text->SetInput("Yaw");
      vtkTextProperty* tprop = text->GetTextProperty();
      tprop->SetFontFamilyToArial();
      tprop->ShadowOff();
      tprop->SetLineSpacing(1.0);
      tprop->SetFontSize(36);
      tprop->SetColor(a1Actor->GetProperty()->GetColor());
      text->SetDisplayPosition(20, 50);
      ren1->AddActor2D(text);

      // Create a TextActor for Pitch  (a3 and a4 actor's color)
      vtkSmartPointer<vtkTextActor> text2 = vtkSmartPointer<vtkTextActor>::New();
      text2->SetInput("Pitch");
      tprop = text2->GetTextProperty();
      tprop->SetFontFamilyToArial();
      tprop->ShadowOff();
      tprop->SetLineSpacing(1.0);
      tprop->SetFontSize(36);
      tprop->SetColor(a3Actor->GetProperty()->GetColor());
      text2->SetDisplayPosition(20, 100);
      ren1->AddActor2D(text2);

      // Create a TextActor for roll (a6 actor's color)
      vtkSmartPointer<vtkTextActor> text3 = vtkSmartPointer<vtkTextActor>::New();
      text3->SetInput("Roll");
      tprop = text3->GetTextProperty();
      tprop->SetFontFamilyToArial();
      tprop->ShadowOff();
      tprop->SetLineSpacing(1.0);
      tprop->SetFontSize(36);
      tprop->SetColor(a6Actor->GetProperty()->GetColor());
      text3->SetDisplayPosition(20, 150);
      ren1->AddActor2D(text3);

      iren->Initialize();
      iren->Start();

      return EXIT_SUCCESS;
    }

### CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)

    PROJECT(CameraModel2)

    find_package(VTK REQUIRED)
    include(${VTK_USE_FILE})

    add_executable(CameraModel2 MACOSX_BUNDLE CameraModel2.cxx )

    target_link_libraries(CameraModel2 ${VTK_LIBRARIES})

### Download and Build CameraModel2

Click here to download CameraModel2 and its CMakeLists.txt file. Once the tarball CameraModel2.tar has been downloaded and extracted,

    cd CameraModel2/build

If VTK is installed:

    cmake ..

If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:

    cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

    make

and run it:

    ./CameraModel2

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.