Математические операции

В основе геометрии CesiumJS лежит трёхмерная система координат, где большинство объектов представляется в виде векторов типа Cartesian3. Этот тип инкапсулирует координаты в пространстве и используется для вычислений положений, направлений, скоростей и любых пространственных преобразований.

Ключевые операции над векторами реализованы в Cesium.Cartesian3:

  • сложение и вычитание векторов
  • масштабирование на скаляр
  • нормализация
  • скалярное и векторное произведение
  • вычисление длины

Базовые операции

const a = new Cesium.Cartesian3(1.0, 2.0, 3.0);
const b = new Cesium.Cartesian3(4.0, 5.0, 6.0);

const sum = Cesium.Cartesian3.add(a, b, new Cesium.Cartesian3());
const diff = Cesium.Cartesian3.subtract(a, b, new Cesium.Cartesian3());
const scaled = Cesium.Cartesian3.multiplyByScalar(a, 2.0, new Cesium.Cartesian3());

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

Длина и нормализация

const length = Cesium.Cartesian3.magnitude(a);

const normalized = Cesium.Cartesian3.normalize(
    a,
    new Cesium.Cartesian3()
);

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

Скалярное и векторное произведение

Скалярное произведение применяется для вычисления углов между направлениями, освещения и проекций.

const dot = Cesium.Cartesian3.dot(a, b);

Геометрический смысл:

  • dot > 0 — угол острый
  • dot = 0 — векторы перпендикулярны
  • dot < 0 — угол тупой

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

const cross = Cesium.Cartesian3.cross(a, b, new Cesium.Cartesian3());

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

Работа с углами и единицами измерения

CesiumJS оперирует радианами как основной единицей углов.

const rad = Cesium.Math.toRadians(90.0);
const deg = Cesium.Math.toDegrees(Math.PI);

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

Дополнительные математические утилиты:

const clamped = Cesium.Math.clamp(value, min, max);
const lerped = Cesium.Math.lerp(a, b, t);
const sign = Cesium.Math.sign(value);

Функция lerp используется для линейной интерполяции между значениями:

a + t(b - a)

Интерполяция в пространстве

Интерполяция координат применяется при анимации камеры, движения объектов и сглаживании траекторий.

Для векторов:

const result = Cesium.Cartesian3.lerp(
    start,
    end,
    t,
    new Cesium.Cartesian3()
);

Для географических координат:

const geoStart = Cesium.Cartographic.fromCartesian(start);
const geoEnd = Cesium.Cartographic.fromCartesian(end);

const interpolated = new Cesium.Cartographic(
    Cesium.Math.lerp(geoStart.longitude, geoEnd.longitude, t),
    Cesium.Math.lerp(geoStart.latitude, geoEnd.latitude, t),
    Cesium.Math.lerp(geoStart.height, geoEnd.height, t)
);

Системы координат и преобразования

CesiumJS активно оперирует несколькими системами координат:

  • Cartesian3 (ECEF — Earth-Centered, Earth-Fixed)
  • Cartographic (широта, долгота, высота)
  • локальные системы координат (ENU — East-North-Up)

Преобразование между системами

const cartographic = Cesium.Cartographic.fromDegrees(
    55.7558,
    37.6173,
    100.0
);

const cartesian = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);

Обратное преобразование:

const back = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian);

Эллипсоид WGS84 определяет модель Земли и влияет на точность вычислений.

Локальные системы координат

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

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

Матрица преобразования позволяет переводить локальные координаты в мировые:

const local = new Cesium.Cartesian4(1.0, 0.0, 0.0, 1.0);
const world = Cesium.Matrix4.multiplyByPoint(
    enuTransform,
    Cesium.Cartesian3.fromCartesian4(local),
    new Cesium.Cartesian3()
);

Матрицы преобразований

CesiumJS использует матрицы 3x3 и 4x4 для описания трансформаций:

  • Matrix3 — вращение и масштаб
  • Matrix4 — полный аффинный трансформ (вращение + масштаб + перенос)

Основные операции

const identity = Cesium.Matrix4.IDENTITY;

const translation = Cesium.Matrix4.fromTranslation(
    new Cesium.Cartesian3(10.0, 0.0, 0.0)
);

Умножение матриц:

const result = Cesium.Matrix4.multiply(
    a,
    b,
    new Cesium.Matrix4()
);

Применение к точке:

const transformed = Cesium.Matrix4.multiplyByPoint(
    matrix,
    point,
    new Cesium.Cartesian3()
);

Кватернионы и вращения

Кватернионы используются для описания вращений без эффекта гимбал-лока.

const axis = Cesium.Cartesian3.UNIT_Z;
const angle = Cesium.Math.toRadians(45.0);

const quat = Cesium.Quaternion.fromAxisAngle(axis, angle);

Преобразование в матрицу вращения:

const rotationMatrix = Cesium.Matrix3.fromQuaternion(quat);

Композиция вращений:

const combined = Cesium.Quaternion.multiply(q1, q2, new Cesium.Quaternion());

Проекции и вычисление расстояний

Расстояния между точками в CesiumJS вычисляются в 3D-пространстве:

const distance = Cesium.Cartesian3.distance(a, b);

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

const geodesic = new Cesium.EllipsoidGeodesic(
    Cesium.Cartographic.fromDegrees(lon1, lat1),
    Cesium.Cartographic.fromDegrees(lon2, lat2)
);

const surfaceDistance = geodesic.surfaceDistance;

Нормали и геометрические вычисления

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

const p1 = Cesium.Cartesian3.fromDegrees(0, 0);
const p2 = Cesium.Cartesian3.fromDegrees(1, 0);
const p3 = Cesium.Cartesian3.fromDegrees(0, 1);

const v1 = Cesium.Cartesian3.subtract(p2, p1, new Cesium.Cartesian3());
const v2 = Cesium.Cartesian3.subtract(p3, p1, new Cesium.Cartesian3());

const normal = Cesium.Cartesian3.cross(v1, v2, new Cesium.Cartesian3());
Cesium.Cartesian3.normalize(normal, normal);

Преобразование направлений камеры

Направление камеры выражается через векторы forward, up и right:

const direction = viewer.camera.direction;
const up = viewer.camera.up;
const right = viewer.camera.right;

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

Проекция точки на направление

Проекция используется для определения компоненты вектора вдоль заданного направления:

_{b}(a) = b

Реализация:

const dot = Cesium.Cartesian3.dot(a, b);
const denom = Cesium.Cartesian3.magnitudeSquared(b);

const scalar = dot / denom;

const projection = Cesium.Cartesian3.multiplyByScalar(
    b,
    scalar,
    new Cesium.Cartesian3()
);

Линейные преобразования и цепочки операций

CesiumJS активно использует композицию преобразований:

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

const rotation = Cesium.Matrix4.fromRotationTranslation(
    Cesium.Matrix3.fromQuaternion(quat),
    Cesium.Cartesian3.ZERO
);

const finalMatrix = Cesium.Matrix4.multiply(
    modelMatrix,
    rotation,
    new Cesium.Matrix4()
);

Комбинирование матриц позволяет строить сложные иерархии объектов без потери точности.

Численная стабильность и производительность

Математические операции CesiumJS оптимизированы под высокую частоту кадров:

  • избегается создание лишних объектов
  • операции инлайн-ориентированы
  • используется предвыделение выходных буферов

Особое внимание уделяется нормализации и сравнением чисел с плавающей точкой:

const epsilon = Cesium.Math.EPSILON6;

const equal = Cesium.Math.equalsEpsilon(a, b, epsilon);