I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!

preface

In a TWO-DIMENSIONAL map, we only need to provide latitude and longitude coordinates to locate the specified location, while in a three-dimensional world, latitude and longitude (i.e., the two-dimensional coordinate system) cannot describe the position of an element, so we need to use cartesian coordinate system to describe the position of spatial elements. The specific introduction here is not verbose, in the previous article has been roughly introduced, this article mainly to explain the camera related parameters and the effect that can be made by using the camera and its implementation ideas.

camera

I cut an image in Blender to simulate our camera object. The sphere is cesium’s Earth 🌏, which I think is very vivid. This will help us understand the camera’s perspective and facilitate the subsequent explanation of adjusting camera parameters.

The camera class is defined by position, orientation, and visual cone. The viewing frustum (viewing frustum) is defined by six (upper, lower, left, right, near, and far) planes, each of which can be represented by a Cartesian4 object, where the X, Y, and Z components are defined as unit vectors perpendicular to the plane, and the W component is the distance of the plane from the origin/camera position.

// Create the camera object.
var camera = new Cesium.Camera(scene);
camera.position = new Cesium.Cartesian3();
camera.direction = Cesium.Cartesian3.negate(Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
camera.up = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_Y);
camera.frustum.fov = Cesium.Math.PI_OVER_THREE;
camera.frustum.near = 1.0;
camera.frustum.far = 2.0;
Copy the code

For now, we don’t need to understand such a complex custom implementation, just focus on the way it provides us to change the perspective!

Operating camera

Cesium offers several ways to manipulate the camera: setView, flyTo, and lookAt. Here are the similarities and differences between these three ways

setView(options)

viewer.camera.setView(options)

Set camera position, orientation, and transformations.

Opitons Parameter list:

The name of the type describe
destination Cartesian3 | Rectangle The final position of the camera in the WGS84 coordinate system, or the rectangular area visible from the top down view
orientation Object An object containing the attributes of direction, up, and heading, pitch, and roll
endTransform Matrix4 The transformation matrix of the camera reference coordinate system
convert Boolean Whether to convert the destination from world cool. (I don’t know what this parameter is…)

Usage:

// 1. Set the location in the top-down view.
viewer.camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(-117.16.32.71.15000.0)});// 2 Set the view by azimuth Angle, pitch Angle and roll Angle.
viewer.camera.setView({
    destination : cartesianPosition,
    orientation: {
        heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north)
        pitch : Cesium.Math.toRadians(-90),    // default value (looking down)
        roll : 0.0                             // default value}});// 3. The camera space position remains unchanged, and the azimuth, pitch and roll Angle are changed. .
viewer.camera.setView({
    orientation: {
        heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north)
        pitch : Cesium.Math.toRadians(-90),    // default value (looking down)
        roll : 0.0                             // default value}});// 4. View the rectangle in the top-down view.
viewer.camera.setView({
    destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
});

// 5. Set the camera position using the orientation of the unit vector.
viewer.camera.setView({
    destination : Cesium.Cartesian3.fromDegrees(-122.19.46.25.5000.0),
    orientation : {
        direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734),
        up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552.0.1966022179118339)}});Copy the code

flyTo(options)

viewer.camera.flyTo(options)

The camera flies from its current position to a new spatial position.

Opitons Parameter list (see official documentation for other parameters) :

The name of the type describe
destination Cartesian3 | Rectangle The final position of the camera in the WGS84 coordinate system, or the rectangular area visible from the top down view
orientation Object An object containing the attributes of direction, up, and heading, pitch, and roll
duration Number Flight duration (in seconds). If omitted, a reasonable duration is calculated from the distance flown.
complete Camera~FlightCompleteCallback Functions performed when the flight is complete.
cancel Camera~FlightCompleteCallback Functions performed when the flight is cancelled.
endTransform Matrix4 The transformation matrix of the reference frame in which the camera will be at the end of the flight.
maximumHeight Number Maximum altitude in flight.
easingFunction EasingFunction | EasingFunction~Callback Call the function when you release.

Usage:

// 1. Fly to the location represented in the top-down view
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-117.16.32.71.15000.0)});// 2. Fly to the rectangle represented by the top-down view
viewer.camera.flyTo({
    destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
});

// 3. Orientatin is expressed by unit vector
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-122.19.46.25.5000.0),
    orientation : {
        direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734),
        up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552.0.1966022179118339)}});// 4. Orientatin is indicated by heading, pitch and roll
viewer.camera.flyTo({
    destination : Cesium.Cartesian3.fromDegrees(-122.19.46.25.5000.0),
    orientation : {
        heading : Cesium.Math.toRadians(175.0),
        pitch : Cesium.Math.toRadians(-35.0),
        roll : 0.0}});Copy the code

lookAt(target,offset)

Set the camera position and direction by target and offset. The target is represented in world coordinates. Offset is the Cartesian coordinates or “heading/pitch/range” in the local “east-North-up” reference frame centered on the target. If offset is represented by Cartesian coordinates, it represents the offset from the center of the reference frame defined by the transformation matrix. If the offset is represented by “heading/pitch/range”, the azimuth (heading) and pitch Angle (pitch) are determined by the reference system defined according to the transformation matrix, and the azimuth (heading) increases from y axis to X axis, Pitch refers to the rotation Angle from the XY plane. The positive pitch is located below the plane and the negative pitch is located above the plane. Range is the distance from the center point. In 2D, it must be a top-down view, where the camera is located above the overlooked target and the height above the target is the offset. The azimuth is determined by the offset, or if the azimuth cannot be determined from the offset, the azimuth is north.

viewer.camera.lookAt(target,offset)

Set camera position, orientation, and transformations.

Opitons Parameter list:

The name of the type describe
target Cartesian3 The spatial position of the target in world coordinates.
offset Cartesian3 | HeadingPitchRange The offset from the local “east-north-up” reference frame centered on the target.

Usage:

// 1. Set the offset using Cartesian coordinates
var center = Cesium.Cartesian3.fromDegrees(-98.0.40.0);
viewer.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0.3930000.0));

// 2. Set the offset with HeadingPitchRange
var center = Cesium.Cartesian3.fromDegrees(-72.0.40.0);
var heading = Cesium.Math.toRadians(50.0);
var pitch = Cesium.Math.toRadians(-20.0);
var range = 5000.0;
viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));
Copy the code

Similarities and differences between the three

Firstly, the destination and orientation of the camera object are basically adjusted to achieve the purpose of positioning the specified position. The difference is that flyTo flies into the destination with animation effect. The other two are directly positioned to the corresponding position (as shown in the figure). Next, we will specify the azimuth/pitch/roll Angle in the parameters, because this is closely related to the effect we want to achieve.

setView flyTo lookAt

Heading/Pitch/Roll

These three angles have been annotated in Chinese above

  • Heading: Azimuth

  • Pitch: Pitch Angle

  • Roll: Roll Angle

Now with your smart little brain at the center, heading is like looking left and right, changing left and right, pitch is like looking down, changing up and down, and roll can imagine you’re rolling on your side, and your head is always looking forward, so a roll is like a 360 degree roll.

The following figure visually shows the relationship between perspective and three angles:

HeadingPitchRange and HeadingPitchRoll

Both are used to define a locally used Angle object. The difference between the two is that HeadingPitchRoll is mainly used for model transformations, while HeadingPitchRange is more used for camera and viewpoint-related operations. The following shows the differences between the two parameters.

  • Range: Represents a radius value, that is, the distance from the target to which the camera is locked.

  • Roll: component of roll (in radians)

Practical cases

The camera can do a lot of effects, and the most classic is around the point of flight and roaming, the next two on the two effect to achieve simple implementation.

Fly around point

We’ll start by creating a point to visualize the center of the flight around the point, which we won’t talk about much more, which is the basic creation entity:

var entity = this.GLOBAL.Viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(116.391935.39.907123),
    point: {
        color: Cesium.Color.YELLOW,
        pixelSize: 10,}})Copy the code

Next use zoomTo to position the camera to the point we created, then use onTick to bind a method to run each frame, and adjust our heading (azimuth) in the method to rotate around the point:

var heading = 0 / / towards
var offset = new Cesium.HeadingPitchRange(
    Cesium.Math.toRadians(heading),
    -Cesium.Math.toRadians(30),
    1000
)
this.GLOBAL.Viewer.zoomTo(entity, offset).then(() = > {
    this.GLOBAL.Viewer.clock.onTick.addEventListener(() = > {
        heading += 0.1
        offset = new Cesium.HeadingPitchRange(
        Cesium.Math.toRadians(heading),
        -Cesium.Math.toRadians(30),
        1000
        )
        this.GLOBAL.Viewer.zoomTo(entity, offset)
        this.GLOBAL.Viewer.scene.screenSpaceCameraController.enableInputs = false})})Copy the code

First person perspective roaming

In the previous articles 【 Cesium | using Property mechanism for trajectory playback 】 we have achieved in the trajectory playback, now we can use the camera and transformation to realize fixed point of view.

In the addRoamLine method, we add the fixed perspective method:

// Add roaming routes
addRoamLine(positions, speed) {
    / /...
    this.viewer.trackedEntity = this.animateEntity;
    if (this.isFirstPerson) {
        this.clockEvent = this.viewer.clock.onTick.addEventListener(
        this.firstPersonEvent()
        );
    }
    / /...
}
firstPersonEvent() {
    return () = > {
        if (!this.animateEntity) return;
        if (!this.viewer.trackedEntity) return;

        let center = this.animateEntity.position.getValue(
            this.viewer.clock.currentTime
        );
        let orientation = this.animateEntity.orientation.getValue(
            this.viewer.clock.currentTime
        );
        if (center) {
        let transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);
        transform = Cesium.Matrix4.fromRotationTranslation(
            Cesium.Matrix3.fromQuaternion(orientation),
            center
        );
        this.viewer.camera.lookAtTransform(
            transform,
            new Cesium.Cartesian3(-100.0.50)); }}; }Copy the code

I will share the knowledge related to transform after sorting it out. I was going to write it in this article, but I feel my understanding is not enough… “I am one of the world 鈥 檚 largest buoys