原文链接及内容

示例详解

代码里涉及到的颜色,rgb各个通道范围为0-1的范围,具体如下图所示:如土星的颜色:Cesium.Color(0.95, 0.82, 0.49)

注:这里推荐一个网址:https://rgbcolorpicker.com/0-1 ,方便测试颜色通道范围为0-1的颜色定义。

Cesium.EllipsoidGraphics的常用属性:outlineColor默认为黑色,outlineWidth默认值为1.0。

  • radii: 单词radius的复数,半径,获取或设置指定椭球体半径。
  • innerRadii: 获取或设置指定椭球体内半径。
  • minimumCone: 获取或设置指定椭圆体最小锥角,默认值为0.0。
  • maximumCone: 获取或设置指定椭圆体最大锥角,默认值为PI。
  • slicePartitions: 水平细分,获取或设置每 360 度径向切片(slice)数量的属性。
  • stackPartitions: 垂直细分,设置或获取椭球体在垂直方向上的分层数量。
  • minimumClock: 最小起始角度,默认值为0,它决定了椭球体从哪个角度开始绘制。角度是相对于椭球体的局部坐标系的,0 弧度通常对应于正X轴方向(东向),正值表示逆时针旋转。
  • maximumClock: 最大终止角度,默认值为2*PI,它决定了椭球体绘制到哪个角度结束。

注:在Cesium中,EllipsoidGraphicsminimumClockmaximumClock属性用于控制椭球体在水平方向(经度方向,绕Z轴)的角度范围,从而绘制部分椭球体(例如球体的一个扇形部分);类似地,minimumConemaximumCone控制椭球体在垂直方向(纬度方向)的角度范围。

绘制土星环的原理

绘制土星内环和外环的原理如下图所示:相当于赤道线向南半球和北半球延伸切包裹地球的一个条带。

设置minimumCone和maximumCone属性可以绘制出一个包裹地球的条带

这里为了看出来效果,我们将minimumCone属性设置为80.0maximumCone属性设置为100.0,在上述图示基础上,然后增加radiiinnerRadii属性:即可绘制出一个立体环,上述代码是将南北方位限制在89.8-90.2范围内,使立体环很扁,像一个扁平的环。

注:这里经过测试,从地球北极开始为0,赤道为90,南极为180,弧度范围为0——PI,这里把球体比作地球便于理解。

立体环示意图

综上,我们来看绘制带圆环的土星实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const saturnPosition = Cesium.Cartesian3.fromDegrees(-95.0, 45.0, 300000.0);
viewer.entities.add({
name: "土星",
position: saturnPosition,
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
material: new Cesium.Color(0.95, 0.82, 0.49),
},
});

viewer.entities.add({
name: "土星的内环",
position: saturnPosition,
orientation: Cesium.Transforms.headingPitchRollQuaternion(
saturnPosition,
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(30.0),
Cesium.Math.toRadians(30.0),
0.0,
),
),
ellipsoid: {
radii: new Cesium.Cartesian3(400000.0, 400000.0, 400000.0),
innerRadii: new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),
minimumCone: Cesium.Math.toRadians(89.8),
maximumCone: Cesium.Math.toRadians(90.2),
material: new Cesium.Color(0.95, 0.82, 0.49, 0.5),
},
});

viewer.entities.add({
name: "土星的外环",
position: saturnPosition,
orientation: Cesium.Transforms.headingPitchRollQuaternion(
saturnPosition,
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(30.0),
Cesium.Math.toRadians(30.0),
0.0,
),
),
ellipsoid: {
radii: new Cesium.Cartesian3(460000.0, 460000.0, 460000.0),
innerRadii: new Cesium.Cartesian3(415000.0, 415000.0, 415000.0),
minimumCone: Cesium.Math.toRadians(89.8),
maximumCone: Cesium.Math.toRadians(90.2),
material: new Cesium.Color(0.95, 0.82, 0.49, 0.5),
},
});

实现效果如下图:

带圆环的土星

圆顶

这里没有设置minimumCone属性,但其默认值为0.0maximumCone属性为π/2,我们以地球为例,则为北半球,即半个球体。
这里指定outline属性为true,但是slicePartitions有默认值,其默认值为64,这里需要设置为别的数值进行验证。

1
2
3
4
5
6
7
8
9
10
11
12
viewer.entities.add({
name: "圆顶",
position: Cesium.Cartesian3.fromDegrees(-120.0, 40.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
maximumCone: Cesium.Math.PI_OVER_TWO,
material: Cesium.Color.BLUE.withAlpha(0.3),
outline: true,
slicePartitions: 4,
stackPartitions: 4,
},
});

slicePartitions设置为4,则横截面(赤道面)为一个正(四边)方形:

stackPartitions设置为4,则将南北半球分为4部分,则纵截面是一个正八边形。

综上, 最终效果为带黑色轮廓线的半透明蓝色的圆顶(半个球体),具体如下图所示:

带黑色轮廓线的半透明蓝色的圆顶(半个球体)

带内半径的圆顶

1
2
3
4
5
6
7
8
9
10
11
viewer.entities.add({
name: "带内半径的圆顶",
position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0),
ellipsoid: {
radii: new Cesium.Cartesian3(250000.0, 200000.0, 150000.0),
innerRadii: new Cesium.Cartesian3(100000.0, 80000.0, 60000.0),
maximumCone: Cesium.Math.PI_OVER_TWO,
material: Cesium.Color.RED.withAlpha(0.3),
outline: true,
},
});

具体如下图:

顶部开孔的圆顶

1
2
3
4
5
6
7
8
9
10
11
12
viewer.entities.add({
name: "顶部开孔的圆顶",
position: Cesium.Cartesian3.fromDegrees(-108.0, 40.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
innerRadii: new Cesium.Cartesian3(100000.0, 100000.0, 100000.0),
minimumCone: Cesium.Math.toRadians(20.0),
maximumCone: Cesium.Math.PI_OVER_TWO,
material: Cesium.Color.YELLOW.withAlpha(0.3),
outline: true,
},
});

效果如下图:内半径的高是半径高的一半,内半球和外半球都是从20度到90度范围。

这里将innerRadii属性设置为:innerRadii: new Cesium.Cartesian3(100000.0, 100000.0, 200000.0),,即内半径的高和半径的高是一致的,效果如下:

若内半径的高为半径高的四分之一,效果则为:

顶部和底部都开孔

1
2
3
4
5
6
7
8
9
10
11
12
viewer.entities.add({
name: "顶部和底部都开孔",
position: Cesium.Cartesian3.fromDegrees(-102.0, 40.0, 140000.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
innerRadii: new Cesium.Cartesian3(100000.0, 100000.0, 100000.0),
minimumCone: Cesium.Math.toRadians(60.0),
maximumCone: Cesium.Math.toRadians(140.0),
material: Cesium.Color.DARKCYAN.withAlpha(0.3),
outline: true,
},
});

效果如下:显然是两个同心球体,各自从60度到140度范围,然后就是这种效果

碗(状物)

1
2
3
4
5
6
7
8
9
10
11
viewer.entities.add({
name: "碗(状物)",
position: Cesium.Cartesian3.fromDegrees(-96.0, 39.5, 200000.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
innerRadii: new Cesium.Cartesian3(180000.0, 180000.0, 180000.0),
minimumCone: Cesium.Math.toRadians(110.0),
material: Cesium.Color.GREEN.withAlpha(0.3),
outline: true,
},
});

显然我们将切割的范围设置为110-180,maximumCone默认值为2*PI,则形如一个碗:

水平角度裁剪(绕z轴)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
viewer.entities.add({
name: "水平角度裁剪(绕z轴)",
position: Cesium.Cartesian3.fromDegrees(-90.0, 39.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
innerRadii: new Cesium.Cartesian3(150000.0, 150000.0, 150000.0),
minimumClock: Cesium.Math.toRadians(-90.0),
maximumClock: Cesium.Math.toRadians(180.0),
minimumCone: Cesium.Math.toRadians(20.0),
maximumCone: Cesium.Math.toRadians(70.0),
material: Cesium.Color.BLUE.withAlpha(0.3),
outline: true,
},
});

绕z轴裁剪出来-90度到180度:

部分圆顶

1
2
3
4
5
6
7
8
9
10
11
12
viewer.entities.add({
name: "部分圆顶",
position: Cesium.Cartesian3.fromDegrees(-84.0, 38.5),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 200000.0),
minimumClock: Cesium.Math.toRadians(-90.0),
maximumClock: Cesium.Math.toRadians(180.0),
maximumCone: Cesium.Math.toRadians(90.0),
material: Cesium.Color.RED.withAlpha(0.3),
outline: true,
},
});

绕z轴裁剪出来-90度到180度,比上面的简单,没有设置内半径:

楔子(xiēzi)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
viewer.entities.add({
name: "楔子(xiēzi)",
position: Cesium.Cartesian3.fromDegrees(-102.0, 35.0, 20000.0),
orientation: Cesium.Transforms.headingPitchRollQuaternion(
Cesium.Cartesian3.fromDegrees(-102.0, 35.0, 20000.0),
new Cesium.HeadingPitchRoll(Cesium.Math.PI / 1.5, 0, 0.0),
),
ellipsoid: {
radii: new Cesium.Cartesian3(500000.0, 500000.0, 500000.0),
innerRadii: new Cesium.Cartesian3(10000.0, 10000.0, 10000.0),
minimumClock: Cesium.Math.toRadians(-15.0),
maximumClock: Cesium.Math.toRadians(15.0),
minimumCone: Cesium.Math.toRadians(75.0),
maximumCone: Cesium.Math.toRadians(105.0),
material: Cesium.Color.DARKCYAN.withAlpha(0.3),
outline: true,
},
});

这里内半径和半径的比值为1:50,设置较小范围的Cone和Clock,都为30度,最终形如楔子:

部分椭球体

1
2
3
4
5
6
7
8
9
10
11
12
13
viewer.entities.add({
name: "部分椭球体",
position: Cesium.Cartesian3.fromDegrees(-95.0, 34.0),
ellipsoid: {
radii: new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),
innerRadii: new Cesium.Cartesian3(70000.0, 70000.0, 70000.0),
minimumClock: Cesium.Math.toRadians(180.0),
maximumClock: Cesium.Math.toRadians(400.0),
maximumCone: Cesium.Math.toRadians(90.0),
material: Cesium.Color.DARKCYAN.withAlpha(0.3),
outline: true,
},
});

这里不再分析,形状如下: