Свойства положения и ориентации

В основе работы CesiumJS лежит трёхмерное представление мира в системе координат WGS84. Любая позиция объекта описывается в пространстве через декартовы координаты, чаще всего в виде структуры Cartesian3.

Cartesian3 представляет точку в фиксированной земной системе координат (ECEF — Earth-Centered, Earth-Fixed), где:

  • ось X проходит через экватор и нулевой меридиан,
  • ось Y направлена к 90° восточной долготы,
  • ось Z направлена к северному полюсу.

Такое представление позволяет однозначно определять положение объекта на поверхности Земли и в её околоземном пространстве.

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

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

Преобразование между системами выполняется через функции Cesium:

const cartesian = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);

Использование двух представлений связано с разделением задач: географические координаты удобны для ввода и отображения, декартовы — для вычислений в сцене.


Свойство position в Entity и Property-система

В CesiumJS положение объектов редко задаётся как фиксированная точка. Основной механизм — система Property, обеспечивающая динамическое изменение значений во времени.

Ключевым элементом является position, обычно используемое внутри Entity:

const entity = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 50, 1000)
});

Однако реальная сила системы проявляется при использовании изменяемых свойств.

ConstantPositionProperty

Используется для фиксированного положения:

entity.position = new Cesium.ConstantPositionProperty(
    Cesium.Cartesian3.fromDegrees(30, 50, 1000)
);

Такой объект не зависит от времени и всегда возвращает одно значение.


SampledPositionProperty

Основной механизм описания движения. Представляет набор значений положения, привязанных ко времени.

const position = new Cesium.SampledPositionProperty();

position.addSample(
    Cesium.JulianDate.fromIso8601("2026-01-01T00:00:00Z"),
    Cesium.Cartesian3.fromDegrees(30, 50, 1000)
);

position.addSample(
    Cesium.JulianDate.fromIso8601("2026-01-01T00:10:00Z"),
    Cesium.Cartesian3.fromDegrees(30.1, 50.1, 1500)
);

entity.position = position;

Cesium автоматически интерполирует промежуточные значения между точками, формируя непрерывное движение.

Интерполяция может быть линейной или сплайновой:

position.setInterpolationOptions({
    interpolationDegree: 2,
    interpolationAlgorithm: Cesium.HermitePolynomialApproximation
});

CallbackProperty

Используется для вычисления положения в реальном времени:

entity.position = new Cesium.CallbackProperty(function(time, result) {
    const t = Cesium.JulianDate.toDate(time).getSeconds();
    return Cesium.Cartesian3.fromDegrees(30 + t * 0.001, 50, 1000);
}, false);

Такой подход применяется при симуляциях, где координаты зависят от внешних данных или алгоритмов.


Интерполяция положения

Интерполяция определяет, как Cesium вычисляет промежуточные координаты между заданными точками.

Основные типы:

  • линейная интерполяция,
  • полиномиальная (Hermite),
  • Lagrange-подобные методы (через встроенные алгоритмы).

Линейная модель:

P(t) = (1 - s) * P0 + s * P1

где s — нормализованный параметр времени.

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


Ориентация объектов в пространстве

Ориентация задаёт поворот объекта относительно глобальной системы координат. В CesiumJS для этого используется тип Quaternion и производные представления.

Quaternion

Кватернион представляет вращение без проблем гимбал-лока и используется внутри движка:

const orientation = Cesium.Quaternion.fromHeadingPitchRoll(
    new Cesium.HeadingPitchRoll(
        Cesium.Math.toRadians(90),
        0,
        0
    )
);

HeadingPitchRoll

Более удобное представление ориентации:

  • heading — поворот вокруг оси Z (курс),
  • pitch — наклон вверх/вниз,
  • roll — крен.
const hpr = new Cesium.HeadingPitchRoll(
    Cesium.Math.toRadians(45),
    0,
    0
);

Преобразование в кватернион:

const quat = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr
);

Свойство orientation в Entity

Ориентация, как и положение, может быть статической или динамической.

ConstantProperty для ориентации

entity.orientation = Cesium.Transforms.headingPitchRollQuaternion(
    Cesium.Cartesian3.fromDegrees(30, 50, 1000),
    new Cesium.HeadingPitchRoll(0, 0, 0)
);

VelocityOrientationProperty

Автоматическое вычисление ориентации на основе скорости движения.

entity.orientation = new Cesium.VelocityOrientationProperty(entity.position);

Такой механизм часто используется для объектов, движущихся по маршруту: самолётов, автомобилей, спутников.


Связь положения и ориентации

Положение и ориентация тесно связаны при размещении объектов в локальной системе координат.

Основной подход — построение матрицы преобразования:

const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(30, 50, 1000)
);

Эта матрица определяет локальную систему координат:

  • East — восток,
  • North — север,
  • Up — вверх относительно поверхности эллипсоида.

Использование ModelMatrix

При работе с 3D-моделями часто применяется комбинированная трансформация:

const position = Cesium.Cartesian3.fromDegrees(30, 50, 1000);
const hpr = Cesium.HeadingPitchRoll.fromDegrees(90, 0, 0);

const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

const entity = viewer.entities.add({
    position: position,
    orientation: orientation,
    model: {
        uri: "model.glb"
    }
});

Здесь положение задаёт точку размещения, а ориентация — поворот модели в локальной системе координат.


Различие ориентации Billboard и Model

Billboard-объекты игнорируют полноценную 3D-ориентацию и всегда обращены к камере. Их положение учитывается, но вращение ограничено:

entity.billboard = {
    image: "icon.png",
    rotation: 0
};

Модели же используют полную ориентацию через quaternion и matrix transformations.


Динамическая привязка ориентации к движению

При использовании SampledPositionProperty ориентация может вычисляться на основе производной положения (скорости).

const position = new Cesium.SampledPositionProperty();

position.addSample(time1, pos1);
position.addSample(time2, pos2);

entity.position = position;
entity.orientation = new Cesium.VelocityOrientationProperty(position);

Такой механизм позволяет автоматически направлять объект вдоль траектории без ручного вычисления углов.


Пространственно-временные сущности

CesiumJS рассматривает объекты как функции времени:

  • position(t) → Cartesian3
  • orientation(t) → Quaternion

Такое представление позволяет описывать не статические сцены, а динамические модели мира, где каждая сущность существует как траектория в четырёхмерном пространстве (x, y, z, t).


Координатные преобразования для ориентации

Для корректного размещения объектов используется преобразование локальных осей в глобальные:

const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);

Далее к этой матрице могут добавляться дополнительные вращения:

const rotation = Cesium.Matrix3.fromQuaternion(orientation);
const modelMatrix = Cesium.Matrix4.multiplyByMatrix3(
    transform,
    rotation,
    new Cesium.Matrix4()
);

Поведение ориентации в зависимости от эллипсоида

Cesium учитывает форму Земли, поэтому локальные оси не совпадают с глобальными декартовыми направлениями. Это приводит к необходимости постоянного пересчёта:

  • восток и север зависят от текущей точки,
  • ось “вверх” совпадает с нормалью к эллипсоиду.

Такой подход обеспечивает корректное отображение объектов на всей поверхности планеты, включая высокие широты и сложные географические области.