Боксы и сферы

Трёхмерные сцены часто содержат простые геометрические объекты, которые используются как самостоятельные элементы визуализации, вспомогательные маркеры, ограничивающие объёмы, контейнеры данных или базовые строительные блоки сложных моделей. В CesiumJS для этих задач предусмотрены специальные графические примитивы, позволяющие отображать боксы (Box) и сферы (Sphere) непосредственно на глобусе или в трёхмерном пространстве.

Боксы и сферы могут создаваться через систему Entity API, обеспечивающую высокоуровневый интерфейс работы с объектами сцены.


Создание бокса

Бокс представляет собой прямоугольный параллелепипед, задаваемый тремя размерами:

  • ширина (ось X);
  • глубина (ось Y);
  • высота (ось Z).

Простейший пример:

const boxEntity = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        37.6176,
        55.7558,
        5000
    ),
    box: {
        dimensions: new Cesium.Cartesian3(
            1000,
            1000,
            1000
        ),
        material: Cesium.Color.BLUE
    }
});

В данном примере создаётся куб со стороной 1000 метров.

Параметр dimensions всегда принимает объект Cartesian3, где:

new Cesium.Cartesian3(
    width,
    depth,
    height
)

Прямоугольный параллелепипед

Размеры по каждой оси могут различаться.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        30.3141,
        59.9386,
        3000
    ),
    box: {
        dimensions: new Cesium.Cartesian3(
            5000,
            2000,
            1000
        ),
        material: Cesium.Color.ORANGE
    }
});

Получается вытянутый объект:

  • длина — 5000 м;
  • ширина — 2000 м;
  • высота — 1000 м.

Материалы боксов

Как и другие геометрические объекты CesiumJS, боксы поддерживают различные материалы.

Однотонный цвет

material: Cesium.Color.RED

Полупрозрачность

material: Cesium.Color.RED.withAlpha(0.5)

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


Изображение

material: "./textures/metal.jpg"

Либо:

material: new Cesium.ImageMaterialProperty({
    image: "./textures/metal.jpg"
})

Шахматный узор

material: new Cesium.CheckerboardMaterialProperty({
    evenColor: Cesium.Color.WHITE,
    oddColor: Cesium.Color.BLACK,
    repeat: new Cesium.Cartesian2(8, 8)
})

Такой материал часто используется для тестирования визуализации.


Контуры боксов

Для отображения рёбер используется параметр outline.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        40,
        50,
        2000
    ),
    box: {
        dimensions: new Cesium.Cartesian3(
            3000,
            3000,
            3000
        ),
        material: Cesium.Color.GREEN,
        outline: true,
        outlineColor: Cesium.Color.BLACK
    }
});

Настройки:

outline: true,
outlineColor: Cesium.Color.YELLOW

Только каркас

При необходимости можно скрыть заливку и оставить лишь рёбра.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        20,
        40,
        1000
    ),
    box: {
        dimensions: new Cesium.Cartesian3(
            5000,
            5000,
            5000
        ),
        fill: false,
        outline: true,
        outlineColor: Cesium.Color.CYAN
    }
});

Подобное представление удобно для отладки пространственных расчётов.


Поворот бокса

По умолчанию бокс ориентируется относительно локальной системы координат точки размещения.

Изменение ориентации выполняется через свойство orientation.

const position = Cesium.Cartesian3.fromDegrees(
    37.6176,
    55.7558,
    0
);

const heading = Cesium.Math.toRadians(45);

viewer.entities.add({
    position: position,
    orientation:
        Cesium.Transforms.headingPitchRollQuaternion(
            position,
            new Cesium.HeadingPitchRoll(
                heading,
                0,
                0
            )
        ),
    box: {
        dimensions: new Cesium.Cartesian3(
            4000,
            2000,
            1000
        ),
        material: Cesium.Color.BLUE
    }
});

Используются три угла:

  • Heading — вращение вокруг вертикальной оси;
  • Pitch — наклон вперёд/назад;
  • Roll — крен.

Динамическое изменение размеров

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

const box = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        35,
        55
    ),
    box: {
        dimensions: new Cesium.Cartesian3(
            1000,
            1000,
            1000
        ),
        material: Cesium.Color.RED
    }
});

Изменение размеров:

let size = 1000;

setInterval(() => {
    size += 100;

    box.box.dimensions =
        new Cesium.Cartesian3(
            size,
            size,
            size
        );
}, 100);

Объект будет постепенно увеличиваться.


Создание сферы

Сфера реализована через объект EllipsoidGraphics.

Если все радиусы одинаковы, получается идеальная сфера.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        37.6176,
        55.7558,
        10000
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            3000,
            3000,
            3000
        ),
        material: Cesium.Color.RED
    }
});

Здесь радиус сферы составляет 3000 метров.


Эллипсоид и сфера

Объект ellipsoid позволяет задавать различные радиусы по каждой оси.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        10,
        50,
        5000
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            5000,
            3000,
            2000
        ),
        material: Cesium.Color.ORANGE
    }
});

Получается эллипсоид вращения.

Если:

radii: new Cesium.Cartesian3(
    r,
    r,
    r
)

то объект становится сферой.


Полупрозрачные сферы

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

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        30,
        60
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            10000,
            10000,
            10000
        ),
        material:
            Cesium.Color.BLUE.withAlpha(0.3)
    }
});

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


Контуры сфер

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        25,
        55
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            5000,
            5000,
            5000
        ),
        material: Cesium.Color.WHITE,
        outline: true,
        outlineColor: Cesium.Color.BLACK
    }
});

Визуально отображаются границы геометрии.


Отображение только каркаса сферы

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        20,
        60
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            8000,
            8000,
            8000
        ),
        fill: false,
        outline: true,
        outlineColor: Cesium.Color.YELLOW
    }
});

Такой режим полезен при визуализации ограничивающих объёмов.


Частичные сферы

CesiumJS позволяет отображать не всю сферу, а только определённую её часть.

Ограничение по долготе

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        40,
        55
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            6000,
            6000,
            6000
        ),
        minimumClock:
            Cesium.Math.toRadians(0),
        maximumClock:
            Cesium.Math.toRadians(180),
        material: Cesium.Color.GREEN
    }
});

Получается половина сферы.


Ограничение по широте

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        40,
        45
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            5000,
            5000,
            5000
        ),
        minimumCone:
            Cesium.Math.toRadians(30),
        maximumCone:
            Cesium.Math.toRadians(120),
        material: Cesium.Color.BLUE
    }
});

Можно формировать купола, сегменты и другие пространственные фигуры.


Динамическое изменение радиуса

Радиус сферы может изменяться во времени.

const sphere = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        30,
        55
    ),
    ellipsoid: {
        radii: new Cesium.Cartesian3(
            1000,
            1000,
            1000
        ),
        material:
            Cesium.Color.CYAN.withAlpha(0.4)
    }
});

Анимация расширения:

let radius = 1000;

viewer.clock.onTick.addEventListener(() => {
    radius += 20;

    sphere.ellipsoid.radii =
        new Cesium.Cartesian3(
            radius,
            radius,
            radius
        );
});

Такой подход часто применяется для отображения:

  • распространения сигнала;
  • радиолокационного сканирования;
  • зон обнаружения;
  • моделирования ударных волн.

Bounding Volume и практическое применение

Боксы и сферы широко используются как ограничивающие объёмы (Bounding Volumes).

Сфера удобна благодаря простоте вычислений:

distance <= radius

Проверка попадания точки внутрь сферы требует лишь вычисления расстояния до центра.


Бокс обеспечивает более точное описание пространства.

Например:

const width = 1000;
const depth = 500;
const height = 200;

const inside =
    Math.abs(x) <= width / 2 &&
    Math.abs(y) <= depth / 2 &&
    Math.abs(z) <= height / 2;

Такие объёмы применяются для:

  • пространственных индексов;
  • систем столкновений;
  • отсечения невидимых объектов;
  • геоинформационных расчётов;
  • определения областей интереса.

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

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

Пульсирующая сфера

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        30,
        55
    ),
    ellipsoid: {
        radii: new Cesium.CallbackProperty(
            function(time) {

                const radius =
                    3000 +
                    Math.sin(
                        Cesium.JulianDate.secondsDifference(
                            time,
                            viewer.clock.startTime
                        )
                    ) * 1000;

                return new Cesium.Cartesian3(
                    radius,
                    radius,
                    radius
                );
            },
            false
        ),
        material:
            Cesium.Color.RED.withAlpha(0.4)
    }
});

Пульсирующий бокс

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
        40,
        50
    ),
    box: {
        dimensions:
            new Cesium.CallbackProperty(
                function(time) {

                    const value =
                        3000 +
                        Math.sin(
                            Cesium.JulianDate.secondsDifference(
                                time,
                                viewer.clock.startTime
                            )
                        ) * 500;

                    return new Cesium.Cartesian3(
                        value,
                        value,
                        value
                    );
                },
                false
            ),
        material:
            Cesium.Color.GREEN.withAlpha(0.5)
    }
});

Механизм CallbackProperty является одним из наиболее мощных инструментов CesiumJS для построения динамических трёхмерных сцен.


Сравнение боксов и сфер

Характеристика Box Sphere
Геометрия Параллелепипед Сфера
Размеры Три независимых размера Один или три радиуса
Точность описания пространства Высокая Средняя
Скорость вычислений Высокая Очень высокая
Подходит для зон действия Частично Отлично
Подходит для зданий и контейнеров Отлично Ограниченно
Подходит для bounding volume Отлично Отлично
Поддержка анимации Да Да
Поддержка прозрачности Да Да

Производительность при работе с большим количеством объектов

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

  • использовать Entity API только для объектов, требующих интерактивности;
  • применять Primitive API для массовой визуализации;
  • минимизировать количество обновлений свойств в каждом кадре;
  • избегать создания новых объектов Cartesian3 внутри циклов рендеринга;
  • использовать CallbackProperty только там, где действительно необходима динамика;
  • объединять статические объекты в общие коллекции примитивов.

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