Camera.computeViewRectangle() does not cover all the visible area

1. A concise explanation of the problem you're experiencing.

When I move camera toward South Pole, the view rectangle returned by Camera.computeViewRectangle() does not contain all the visible area.

However, when the south pole is on the center of screen, I can get the result I want.

How can I get a view rectangle that always cover all visible area?

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

I made a SandCastle

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I want to draw primitives only in visible area

4. The Cesium version you're using, your operating system and browser.

Cesium 1.55

I think the rectangle itself (its four corners) are computed correctly, but the rendered rectangle on the globe adheres to the curved surface so there will be areas missing like that on the poles.

I don’t think you can specify the arc type on a rectangle but notice the difference when you change the arcType on the last polygon here, from RHUMB to GEODESIC:

I think what you might want to visualize here is a geometry that doesn’t adhere to the surface, which I think would be a CoplanarGeometry:

https://cesiumjs.org/Cesium/Build/Documentation/CoplanarPolygonGeometry.html?classFilter=Coplan

But it isn’t currently hooked up to the Entity API.

Thanks for sharing your knowledge!

However, another strange thing is that the latitude sometimes jump suddenly in south/north pole area.

In two screenshots I attach, you can see the latitude (shown in the left upper corner) jump from -58.0 to -90.0 with a minor mouse movement.

Besides, 58.0 degrees south does not pass the Antarctic Circle at all


Why the view rectangle give me 58.0 degrees south?

I’ve been having similar issues with computeViewRectangle not necessarily just near the poles, but as you get further from the equator it gets skinnier until it is a line. It is especially inaccurate when north is not up and the camera is pitched. I ended up getting what I wanted with my own custom function (I’m drawing the rectangle in d3.js on a little mini globe but you could use the array of coordinates however you wish). I’m sure there is a more elegant way to write this but it was my first pass and I haven’t refactored. Also, if you have terrain you should use pickPosition instead of pickEllipsoid but it still seems to be working (maybe just less accurate). If the bottom right or bottom left are in outer space it returns undefined.


getCustomViewRectCoordinates() {

let canvas = scene.canvas,

w = canvas.clientWidth,

h = canvas.clientHeight,

tryPixel = 0;

let topLeft = new Cesium.Cartesian2(0, tryPixel);

topLeft = viewer.camera.pickEllipsoid(topLeft, scene.globe.ellipsoid);

let topRight = new Cesium.Cartesian2(w, tryPixel);

topRight = viewer.camera.pickEllipsoid(topRight, scene.globe.ellipsoid);

let bottomLeft = new Cesium.Cartesian2(0, h);

bottomLeft = viewer.camera.pickEllipsoid(bottomLeft, scene.globe.ellipsoid);

let bottomRight = new Cesium.Cartesian2(w, h);

bottomRight = viewer.camera.pickEllipsoid(

bottomRight,

scene.globe.ellipsoid

);

while (

((!topLeft && bottomLeft) || (!topRight && bottomRight)) &&

tryPixel < h

) {

tryPixel += 1;

topLeft = new Cesium.Cartesian2(0, tryPixel);

topLeft = viewer.camera.pickEllipsoid(topLeft, scene.globe.ellipsoid);

topRight = new Cesium.Cartesian2(w, tryPixel);

topRight = viewer.camera.pickEllipsoid(topRight, scene.globe.ellipsoid);

}

if (topLeft && topRight && bottomLeft && bottomRight) {

topLeft = Cesium.Cartographic.fromCartesian(topLeft);

topRight = Cesium.Cartographic.fromCartesian(topRight);

bottomLeft = Cesium.Cartographic.fromCartesian(bottomLeft);

bottomRight = Cesium.Cartographic.fromCartesian(bottomRight);

let coordinates = [topLeft, topRight, bottomRight, bottomLeft, topLeft];

return coordinates.map(c => [

Cesium.Math.toDegrees(c.longitude),

Cesium.Math.toDegrees(c.latitude)

])

}

}