/**
  * Zooms the camera around the specified focus coordinates.
  *
  * @param focusX the x coordinate to focus on
  * @param focusY the y coordinate to focus on
  * @param factor the zoom will be scaled by this factor
  */
 public void zoom(double focusX, double focusY, double factor) {
   synchronized (mutex) {
     Transform focus = Transform.translation(toMetricCoordinates((int) focusX, (int) focusY));
     double zoom = RosMath.clamp(getZoom() * factor, MINIMUM_ZOOM, MAXIMUM_ZOOM) / getZoom();
     transform = transform.multiply(focus).scale(zoom).multiply(focus.invert());
   }
 }
 /**
  * Rotates the camera round the specified coordinates.
  *
  * @param focusX the x coordinate to focus on
  * @param focusY the y coordinate to focus on
  * @param deltaAngle the camera will be rotated by {@code deltaAngle} radians
  */
 public void rotate(double focusX, double focusY, double deltaAngle) {
   synchronized (mutex) {
     Transform focus = Transform.translation(toMetricCoordinates((int) focusX, (int) focusY));
     transform =
         transform
             .multiply(focus)
             .multiply(Transform.zRotation(deltaAngle))
             .multiply(focus.invert());
   }
 }
 /**
  * @return the metric coordinates of the provided pixel coordinates where the origin is the top
  *     left corner of the view
  */
 public Vector3 toMetricCoordinates(int x, int y) {
   double centeredX = x - viewport.getWidth() / 2.0d;
   double centeredY = viewport.getHeight() / 2.0d - y;
   return transform.invert().apply(new Vector3(centeredX, centeredY, 0));
 }