从 Cesium.Cartesian3 和 Cesium.HeadingPitchRoll 创建 Cesium.Ray
Create Cesium.Ray from Cesium.Cartesian3 and Cesium.HeadingPitchRoll
是否可以从 Cesium.Cartesian3
和 Cesium.HeadingPitchRoll
创建一个 Cesium.Ray
?
如果是这样,你会怎么做?
编辑 1:
const hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0)
const matrix3 = Cesium.Matrix3.fromHeadingPitchRoll(hpr)
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
const direction = Cesium.Matrix3.multiplyByVector(
matrix3,
Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3()
)
const origin = Cesium.Cartesian3.fromDegrees(i.longitude, i.latitude, i.altitude)
// Now we can construct the Ray.
const ray = new Cesium.Ray(origin, direction)
const finalPoint = Cesium.Ray.getPoint(ray, i.altitude)
const e = map.viewer.entities.add({
name: i.id,
polyline: {
positions: [origin, finalPoint],
width: 4,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
},
})
将 HPR 设置为 (0,0,0),结果为:
间距为 0,我希望光线与 horizon 平行,而不是看起来像 +45 度。
是的,这是可能的。这两种对象包含不同类型的信息,因此请注意不要在转换过程中丢失数据。
一个Ray
有一个origin
(笛卡尔位置)和一个direction
,它只是一个单位向量,与完整方向不同。
HeadingPitchRoll
是一个完整的方向。 Heading 和 Pitch 共同确定特定的“前进”方向,Roll 表示围绕该方向矢量的旋转。此 Roll 旋转不影响方向,因此不会对 Ray 产生影响。
代码如下:
// A Cesium Ray consists of an "origin" and a "direction".
// The origin is just a Cartesian3 from anywhere.
var origin = new Cesium.Cartesian3(1.0, 2.0, 3.0);
// For this question, "direction" comes from a HeadingPitchRoll.
// Let's establish an HPR here.
var heading = Cesium.Math.toRadians(0); // YOUR VALUE HERE
var pitch = Cesium.Math.toRadians(0); // YOUR VALUE HERE
var roll = Cesium.Math.toRadians(0); // This one does nothing.
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
// Next we need a direction vector from the HPR. We'll use
// a rotation matrix (3x3) to do the conversion.
var matrix3 = Cesium.Matrix3.fromHeadingPitchRoll(hpr);
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
var direction = Cesium.Matrix3.multiplyByVector(matrix3, Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3());
// Now we can construct the Ray.
var ray = new Cesium.Ray(origin, direction);
console.log('Ray: ' + JSON.stringify(ray));
如果您 运行 使用此处显示的默认零 heading/pitch,您将再次获得单位 X 向量:
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":1,"y":0,"z":0}}
但是如果你将俯仰设置为 45 度:
var heading = Cesium.Math.toRadians(0);
var pitch = Cesium.Math.toRadians(45);
您会看到 X 方向已向上倾斜到 +Z。
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":0.7071067811865476,"y":0,"z":0.7071067811865475}}
正航向会将 X 矢量旋转到 -Y(从上面的 +Z 方向看是顺时针方向)。
var heading = Cesium.Math.toRadians(45);
var pitch = Cesium.Math.toRadians(0);
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":0.7071067811865476,"y":-0.7071067811865475,"z":0}}
EDIT: 问题修改了一下。射线的方向需要在以地球为中心的固定坐标系中,而不是局部向上坐标系,以用于预期用途。
这里有一个更长的演示,展示了如何处理这个问题。您也可以在 Sandcastle 上 view a live demo。
var viewer = new Cesium.Viewer("cesiumContainer");
const i = {
id: 'test',
longitude: -79,
latitude: 40,
altitude: 500
};
// Create the origin and hpr.
const origin = Cesium.Cartesian3.fromDegrees(i.longitude, i.latitude, i.altitude)
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0)
// Cesium uses East-North-Up axes, where East is zero. If you want North == Zero,
// you must subtract 90 degrees' worth of radians (pi/2).
hpr.heading -= Cesium.Math.PI_OVER_TWO
// We'll get the orientation, which is a quaternion. This is specific to the
// location on the planet. Also it comes in handy later for the 3D model vis.
const orientation = Cesium.Transforms.headingPitchRollQuaternion(origin, hpr);
// Get a Matrix3 version of that Quaternion.
const matrix3 = Cesium.Matrix3.fromQuaternion(orientation);
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
const direction = Cesium.Matrix3.multiplyByVector(
matrix3,
Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3()
)
// Now we can construct the Ray.
const ray = new Cesium.Ray(origin, direction)
const finalPoint = Cesium.Ray.getPoint(ray, i.altitude)
const e = viewer.entities.add({
name: i.id,
polyline: {
positions: [origin, finalPoint],
width: 4,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
},
})
// Optionally, show an aircraft model with this HPR.
const m = viewer.entities.add({
position: origin,
orientation: orientation,
model: {
uri: "../SampleData/models/CesiumAir/Cesium_Air.glb",
minimumPixelSize: 64,
}
})
viewer.zoomTo(e)
是否可以从 Cesium.Cartesian3
和 Cesium.HeadingPitchRoll
创建一个 Cesium.Ray
?
如果是这样,你会怎么做?
编辑 1:
const hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0)
const matrix3 = Cesium.Matrix3.fromHeadingPitchRoll(hpr)
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
const direction = Cesium.Matrix3.multiplyByVector(
matrix3,
Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3()
)
const origin = Cesium.Cartesian3.fromDegrees(i.longitude, i.latitude, i.altitude)
// Now we can construct the Ray.
const ray = new Cesium.Ray(origin, direction)
const finalPoint = Cesium.Ray.getPoint(ray, i.altitude)
const e = map.viewer.entities.add({
name: i.id,
polyline: {
positions: [origin, finalPoint],
width: 4,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
},
})
将 HPR 设置为 (0,0,0),结果为:
间距为 0,我希望光线与 horizon 平行,而不是看起来像 +45 度。
是的,这是可能的。这两种对象包含不同类型的信息,因此请注意不要在转换过程中丢失数据。
一个
Ray
有一个origin
(笛卡尔位置)和一个direction
,它只是一个单位向量,与完整方向不同。HeadingPitchRoll
是一个完整的方向。 Heading 和 Pitch 共同确定特定的“前进”方向,Roll 表示围绕该方向矢量的旋转。此 Roll 旋转不影响方向,因此不会对 Ray 产生影响。
代码如下:
// A Cesium Ray consists of an "origin" and a "direction".
// The origin is just a Cartesian3 from anywhere.
var origin = new Cesium.Cartesian3(1.0, 2.0, 3.0);
// For this question, "direction" comes from a HeadingPitchRoll.
// Let's establish an HPR here.
var heading = Cesium.Math.toRadians(0); // YOUR VALUE HERE
var pitch = Cesium.Math.toRadians(0); // YOUR VALUE HERE
var roll = Cesium.Math.toRadians(0); // This one does nothing.
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
// Next we need a direction vector from the HPR. We'll use
// a rotation matrix (3x3) to do the conversion.
var matrix3 = Cesium.Matrix3.fromHeadingPitchRoll(hpr);
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
var direction = Cesium.Matrix3.multiplyByVector(matrix3, Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3());
// Now we can construct the Ray.
var ray = new Cesium.Ray(origin, direction);
console.log('Ray: ' + JSON.stringify(ray));
如果您 运行 使用此处显示的默认零 heading/pitch,您将再次获得单位 X 向量:
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":1,"y":0,"z":0}}
但是如果你将俯仰设置为 45 度:
var heading = Cesium.Math.toRadians(0);
var pitch = Cesium.Math.toRadians(45);
您会看到 X 方向已向上倾斜到 +Z。
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":0.7071067811865476,"y":0,"z":0.7071067811865475}}
正航向会将 X 矢量旋转到 -Y(从上面的 +Z 方向看是顺时针方向)。
var heading = Cesium.Math.toRadians(45);
var pitch = Cesium.Math.toRadians(0);
Ray: {"origin":{"x":1,"y":2,"z":3},"direction":{"x":0.7071067811865476,"y":-0.7071067811865475,"z":0}}
EDIT: 问题修改了一下。射线的方向需要在以地球为中心的固定坐标系中,而不是局部向上坐标系,以用于预期用途。
这里有一个更长的演示,展示了如何处理这个问题。您也可以在 Sandcastle 上 view a live demo。
var viewer = new Cesium.Viewer("cesiumContainer");
const i = {
id: 'test',
longitude: -79,
latitude: 40,
altitude: 500
};
// Create the origin and hpr.
const origin = Cesium.Cartesian3.fromDegrees(i.longitude, i.latitude, i.altitude)
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0)
// Cesium uses East-North-Up axes, where East is zero. If you want North == Zero,
// you must subtract 90 degrees' worth of radians (pi/2).
hpr.heading -= Cesium.Math.PI_OVER_TWO
// We'll get the orientation, which is a quaternion. This is specific to the
// location on the planet. Also it comes in handy later for the 3D model vis.
const orientation = Cesium.Transforms.headingPitchRollQuaternion(origin, hpr);
// Get a Matrix3 version of that Quaternion.
const matrix3 = Cesium.Matrix3.fromQuaternion(orientation);
// The UNIT_X vector is "forward" in Cesium. We'll multiply the rotation
// matrix by that unit vector, to get our direction vector.
const direction = Cesium.Matrix3.multiplyByVector(
matrix3,
Cesium.Cartesian3.UNIT_X,
new Cesium.Cartesian3()
)
// Now we can construct the Ray.
const ray = new Cesium.Ray(origin, direction)
const finalPoint = Cesium.Ray.getPoint(ray, i.altitude)
const e = viewer.entities.add({
name: i.id,
polyline: {
positions: [origin, finalPoint],
width: 4,
arcType: Cesium.ArcType.NONE,
material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
},
})
// Optionally, show an aircraft model with this HPR.
const m = viewer.entities.add({
position: origin,
orientation: orientation,
model: {
uri: "../SampleData/models/CesiumAir/Cesium_Air.glb",
minimumPixelSize: 64,
}
})
viewer.zoomTo(e)