diff --git a/java/F3DJavaBindings.cxx b/java/F3DJavaBindings.cxx
index f57a3be58f..e6cf340211 100644
--- a/java/F3DJavaBindings.cxx
+++ b/java/F3DJavaBindings.cxx
@@ -198,4 +198,4 @@ extern "C"
   {
     GetEngine(env, self)->getWindow().getCamera().resetToBounds();
   }
-}
+}
\ No newline at end of file
diff --git a/library/private/camera_impl.h b/library/private/camera_impl.h
index 17173d74ca..7b480d2751 100644
--- a/library/private/camera_impl.h
+++ b/library/private/camera_impl.h
@@ -50,6 +50,9 @@ class camera_impl : public camera
   camera& setState(const camera_state_t& state) override;
   camera_state_t getState() override;
   void getState(camera_state_t& state) override;
+  angle_deg_t getAzimuth() override;
+  angle_deg_t getYaw() override;
+  angle_deg_t getElevation() override;
 
   camera& dolly(double val) override;
   camera& pan(double right, double up, double forward) override;
diff --git a/library/public/camera.h b/library/public/camera.h
index 670afec571..4e8ec9ecf0 100644
--- a/library/public/camera.h
+++ b/library/public/camera.h
@@ -51,6 +51,15 @@ class F3D_EXPORT camera
   virtual void getState(camera_state_t& state) = 0;
   ///@}
 
+  ///@{ @name Orientation
+  /** Get the azimuth angle of the camera. */
+  virtual angle_deg_t getAzimuth() = 0;
+  /** Get the yaw angle of the camera. */
+  virtual angle_deg_t getYaw() = 0;
+  /** Get the elevation angle of the camera. */
+  virtual angle_deg_t getElevation() = 0;
+  ///@}
+
   ///@{ @name Manipulation
   /// Standard camera manipulation methods. Angles are in degrees.
 
diff --git a/library/src/camera_impl.cxx b/library/src/camera_impl.cxx
index 68e72f9635..13c11e8ba9 100644
--- a/library/src/camera_impl.cxx
+++ b/library/src/camera_impl.cxx
@@ -117,6 +117,55 @@ angle_deg_t camera_impl::getViewAngle()
   return angle;
 }
 
+//----------------------------------------------------------------------------
+angle_deg_t camera_impl::getAzimuth()
+{
+  vtkCamera* cam = this->GetVTKCamera();
+  double pos[3], foc[3];
+  cam->GetPosition(pos);
+  cam->GetFocalPoint(foc);
+  double viewDir[3];
+  vtkMath::Subtract(foc, pos, viewDir);
+  double viewDirProj[2] = { viewDir[0], viewDir[1] };
+  if (vtkMath::Dot2D(viewDirProj, viewDirProj) < VTK_DBL_EPSILON)
+  {
+    return 0.0;
+  }
+  return vtkMath::DegreesFromRadians(atan2(viewDirProj[1], viewDirProj[0]));
+}
+
+//----------------------------------------------------------------------------
+angle_deg_t camera_impl::getYaw()
+{
+  vtkCamera* cam = this->GetVTKCamera();
+  double pos[3], foc[3];
+  cam->GetPosition(pos);
+  cam->GetFocalPoint(foc);
+  double viewDir[3];
+  vtkMath::Subtract(foc, pos, viewDir);
+  double viewDirProj[2] = { viewDir[0], viewDir[2] };
+  if (vtkMath::Dot2D(viewDirProj, viewDirProj) < VTK_DBL_EPSILON)
+  {
+    return 0.0;
+  }
+  return vtkMath::DegreesFromRadians(atan2(viewDirProj[0], viewDirProj[1]));
+}
+
+//----------------------------------------------------------------------------
+angle_deg_t camera_impl::getElevation()
+{
+  vtkCamera* cam = this->GetVTKCamera();
+  double pos[3], foc[3];
+  cam->GetPosition(pos);
+  cam->GetFocalPoint(foc);
+
+  double viewDir[3];
+  vtkMath::Subtract(foc, pos, viewDir);
+  vtkMath::Normalize(viewDir);
+
+  return vtkMath::DegreesFromRadians(asin(viewDir[2]));
+}
+
 //----------------------------------------------------------------------------
 void camera_impl::getViewAngle(angle_deg_t& angle)
 {
diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt
index 44814b2e18..538a19d0d3 100644
--- a/library/testing/CMakeLists.txt
+++ b/library/testing/CMakeLists.txt
@@ -75,6 +75,7 @@ option(F3D_TESTING_ENABLE_EXTERNAL_QT "Test external QT" OFF)
 
 set(libf3dSDKTests_link_libs "")
 
+find_package(VTK REQUIRED COMPONENTS CommonCore)
 if(F3D_TESTING_ENABLE_EXTERNAL_GLFW)
   find_package(glfw3 REQUIRED)
   list(APPEND libf3dSDKTests_list TestSDKExternalWindowGLFW.cxx)
@@ -177,7 +178,7 @@ if(F3D_MODULE_UI AND NOT F3D_TESTING_ENABLE_LONG_TIMEOUT_TESTS)
   set_tests_properties(libf3d::TestSDKInteractorCallBack PROPERTIES DISABLED ON)
 endif()
 
-target_link_libraries(libf3dSDKTests libf3d ${libf3dSDKTests_link_libs})
+target_link_libraries(libf3dSDKTests libf3d ${libf3dSDKTests_link_libs} VTK::CommonCore)
 
 # make sure the libf3d API is compatible with the right C++ standard
 set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 17)
diff --git a/library/testing/TestSDKCamera.cxx b/library/testing/TestSDKCamera.cxx
index 3210f4f210..4208fb4419 100644
--- a/library/testing/TestSDKCamera.cxx
+++ b/library/testing/TestSDKCamera.cxx
@@ -8,6 +8,7 @@
 #include <iostream>
 #include <limits>
 #include <sstream>
+#include <vtkMath.h>
 
 // TODO these methods should be put in types.h at some point.
 // https://github.com/f3d-app/f3d/issues/361
@@ -141,6 +142,19 @@ int TestSDKCamera(int argc, char* argv[])
     return EXIT_FAILURE;
   }
 
+  // Test getAzimuth
+  f3d::point3_t tempPos = { 0.0, 0.0, 0.0 };
+  f3d::point3_t tempFoc = { 0.0, 0.0, 1.0 };
+  cam.setPosition(tempPos);
+  cam.setFocalPoint(tempFoc);
+  f3d::angle_deg_t azimuth = cam.getAzimuth();
+  if (!compareDouble(azimuth, 0.0))
+  {
+    std::cerr << "getAzimuth is not behaving as expected:" << std::endl;
+    std::cerr << std::setprecision(12) << "azimuth: " << azimuth << " != 0.0" << std::endl;
+    return EXIT_FAILURE;
+  }
+
   // Test roll
   cam.roll(90);
   expectedUp = { 0., 0., -1. };
@@ -179,6 +193,19 @@ int TestSDKCamera(int argc, char* argv[])
     return EXIT_FAILURE;
   }
 
+  // Test getYaw
+  // f3d::point3_t testPos = { 0.0, 0.0, 0.0 };
+  f3d::point3_t termFoc = { 0.0, 0.0, 1.0 };
+  // cam.setPosition(testPos);
+  cam.setFocalPoint(termFoc);
+  f3d::angle_deg_t yaw = cam.getYaw();
+  if (!compareDouble(yaw, 0.0))
+  {
+    std::cerr << "getYaw is not behaving as expected:" << std::endl;
+    std::cerr << std::setprecision(12) << "yaw: " << yaw << " != 0.0" << std::endl;
+    return EXIT_FAILURE;
+  }
+
   // Test elevation
   cam.elevation(90);
   expectedPos = { 11., -11., -12. };
@@ -199,6 +226,10 @@ int TestSDKCamera(int argc, char* argv[])
     return EXIT_FAILURE;
   }
 
+  // Test getElevation
+  double elevation = cam.getElevation();
+  checkDouble(elevation, 90.0, "getElevation");
+
   // Test pitch
   cam.pitch(90);
   expectedFoc = { 22., -11., -12. };
diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx
index 71aa2c62db..4c3cf71c76 100644
--- a/python/F3DPythonBindings.cxx
+++ b/python/F3DPythonBindings.cxx
@@ -478,4 +478,4 @@ PYBIND11_MODULE(pyf3d, module)
     .def_static("set_use_coloring", &f3d::log::setUseColoring)
     .def_static("print", [](f3d::log::VerboseLevel& level, const std::string& message)
       { f3d::log::print(level, message); });
-}
+}
\ No newline at end of file