Позиционирование камеры

В CesiumJS камера является центральным инструментом управления сценой, определяющим точку наблюдения, направление взгляда и параметры перспективы. Она интегрирована в Viewer и доступна через viewer.camera, однако фактически работает поверх Scene.camera, расширяя базовый функционал сценического рендера.


Пространственные координаты и основа позиционирования

Камера оперирует в трёхмерном декартовом пространстве, где основным типом координат выступает Cartesian3. Это система, в которой положение точки задаётся тремя компонентами X, Y, Z относительно центра эллипсоида Земли.

Параллельно используется географическое представление через Cartographic, где координаты задаются широтой, долготой и высотой:

  • долгота (longitude)
  • широта (latitude)
  • высота (height)

Преобразование между системами является базовой операцией при позиционировании:

const cartographic = Cesium.Cartographic.fromDegrees(71.4304, 51.1284, 1000);
const position = Cesium.Cartesian3.fromRadians(
    cartographic.longitude,
    cartographic.latitude,
    cartographic.height
);

Такой переход необходим, поскольку камера в сцене всегда использует Cartesian3, тогда как пользовательские данные чаще представлены географическими координатами.


Основные параметры камеры

Камера в CesiumJS описывается тремя ключевыми характеристиками:

  • position — точка расположения в пространстве (Cartesian3)
  • direction — вектор направления взгляда
  • up — вектор “верха”, определяющий ориентацию горизонта

Эти параметры формируют матрицу вида, определяющую преобразование сцены в экранное пространство.

Пример явной установки позиции:

viewer.camera.position = Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 5000);
viewer.camera.direction = Cesium.Cartesian3.normalize(
    Cesium.Cartesian3.subtract(
        Cesium.Cartesian3.fromDegrees(71.5, 51.1, 0),
        viewer.camera.position,
        new Cesium.Cartesian3()
    ),
    new Cesium.Cartesian3()
);
viewer.camera.up = Cesium.Cartesian3.UNIT_Z;

Метод setView: мгновенное позиционирование

setView используется для мгновенного перемещения камеры без анимации. Он принимает либо позицию и ориентацию, либо комбинацию направления и высоты.

Базовая форма:

viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 10000),
    orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-45),
        roll: 0
    }
});

Параметры ориентации:

  • heading — поворот вокруг оси Z (азимут)
  • pitch — наклон вверх/вниз
  • roll — вращение вокруг оси взгляда

setView используется в сценариях, где требуется точная фиксация положения без визуального перехода.


Анимация перемещения: flyTo

Метод flyTo обеспечивает плавный переход камеры между точками, автоматически интерполируя позицию и ориентацию.

viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 15000),
    duration: 3,
    orientation: {
        heading: Cesium.Math.toRadians(90),
        pitch: Cesium.Math.toRadians(-30),
        roll: 0
    }
});

Особенности механизма:

  • интерполяция по кривой в 3D-пространстве
  • автоматическое сглаживание ускорения
  • поддержка коллбеков начала и завершения
  • возможность прерывания текущей анимации

Центрирование на объекте: lookAt

Метод lookAt позволяет фиксировать камеру относительно точки интереса. В этом режиме камера привязывается к цели, сохраняя смещение.

const center = Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 0);
const offset = new Cesium.Cartesian3(0, -1000, 500);

viewer.camera.lookAt(center, offset);

Для возврата в глобальный режим используется сброс трансформации:

viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

lookAt применяется при орбитальном просмотре объектов, анализе рельефа и точечной навигации.


Ориентация через HeadingPitchRoll

Для более точного управления направлением используется структура HeadingPitchRoll, которая описывает углы ориентации в локальной системе координат.

const hpr = new Cesium.HeadingPitchRoll(
    Cesium.Math.toRadians(45),
    Cesium.Math.toRadians(-20),
    0
);

const orientation = Cesium.Transforms.headingPitchRollQuaternion(
    Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 1000),
    hpr
);

Этот подход часто используется при работе с 3D-моделями и объектами, имеющими собственную локальную систему координат.


Динамическое управление камерой

CesiumJS предоставляет низкоуровневые методы управления движением камеры:

  • moveForward(distance)
  • moveBackward(distance)
  • moveUp(distance)
  • moveDown(distance)
  • moveRight(distance)
  • moveLeft(distance)
  • lookRight(angle)
  • lookUp(angle)

Пример последовательного перемещения:

const camera = viewer.camera;

camera.moveForward(1000);
camera.lookRight(Cesium.Math.toRadians(5));
camera.moveUp(200);

Эти методы работают в локальной системе координат камеры и позволяют реализовывать интерактивное управление.


Ограничение движения камеры

Для контроля навигации применяются ограничения, связанные с поверхностью эллипсоида и диапазоном высот.

Основные подходы:

  • установка минимальной и максимальной высоты
  • ограничение наклона камеры
  • использование clampToGround для фиксации на поверхности

Пример ограничения высоты:

viewer.scene.screenSpaceCameraController.minimumZoomDistance = 500;
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 20000000;

Контроллер screenSpaceCameraController отвечает за пользовательскую навигацию мышью и жестами, позволяя детально регулировать поведение камеры.


Работа с bounding sphere и автоматическое позиционирование

При необходимости центрировать камеру на объекте используется BoundingSphere, который описывает сферу, охватывающую геометрию.

const boundingSphere = new Cesium.BoundingSphere(
    Cesium.Cartesian3.fromDegrees(71.4304, 51.1284, 0),
    5000
);

viewer.camera.flyToBoundingSphere(boundingSphere, {
    duration: 2
});

Этот метод автоматически вычисляет оптимальную дистанцию обзора и ориентацию.


Системы трансформации камеры

Камера может работать в различных системах отсчёта:

  • глобальная (Earth-fixed)
  • локальная (ENU — East, North, Up)
  • привязанная к объекту (model transform)

При использовании lookAt или transform камера переходит в локальную систему координат:

const transform = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(71.4304, 51.1284)
);

viewer.camera.lookAtTransform(transform);

Такой подход критичен при работе с 3D-моделями, симуляциями и движущимися объектами.


Практика комбинированного управления

В реальных сценариях управление камерой часто комбинирует несколько методов:

  • мгновенная установка через setView
  • плавные переходы через flyTo
  • локальное наблюдение через lookAt
  • интерактивное управление через move* методы

Сочетание этих механизмов позволяет формировать сложные сценарии навигации, включая автоматические туры, слежение за объектами и интерактивный анализ сцены.