CesiumGS / CesiumGS/cesium

How to make the direction of the real-time point icon rotate according to the direction of the trajectory line movement

Open
#12,835 1 comment 0 reactions 0 assignees View on GitHub
needs feedback type - enhancement
Dominant language
JavaScript
Stars
15.7k
Forks
3.9k
Avg merge
4d 6h
Merged PRs (30d)
34

Description

### Feature

The data is like this`{
"id": null,
"experimentId": "080801",
"experimentName": "080801",
"ts": "62446555",
"orgMsg": "",
"targetId": "1100000000",
"targetType": "DD",
"targetPosX": 6327.27996555,
"targetPosY": 6284.27996555,
"targetPosZ": 102917.0,
"targetVelX": 4.0,
"targetVelY": 5.0,
"targetVelZ": 6.0,
"createTime": null,
"track": [
{
"x": 6313.62930062,
"y": 6270.62930062,
"z": 102917.0,
"state": 0
},
{
"x": 6315.63180085,
"y": 6272.63180085,
"z": 102917.0,
"state": 0
},
{
"x": 6317.6395016,
"y": 6274.6395016,
"z": 102917.0,
"state": 0
},
{
"x": 6319.64000163,
"y": 6276.64000163,
"z": 102917.0,
"state": 0
},
{
"x": 6321.6499026,
"y": 6278.6499026,
"z": 102917.0,
"state": 0
},
{
"x": 6323.65920351,
"y": 6280.65920351,
"z": 102917.0,
"state": 0
},
{
"x": 6325.65950352,
"y": 6282.65950352,
"z": 102917.0,
"state": 0
}
]
}`
The code implementation is
` pointList.value = res.data.map((v) => {
// 将当前位置添加到轨迹末尾
const fullTrack = [
...v.track,
{
x: v.targetPosX,
y: v.targetPosY,
z: v.targetPosZ,
state: 0,
},
];
// 为每个轨迹点计算朝向
for (let i = 0; i < fullTrack.length - 1; i++) {
const current = fullTrack[i];
const next = fullTrack[i + 1];
current.heading = calculateBearing(current.x, current.y, next.x, next.y);
}

return {
...v,
x: v.targetPosX,
y: v.targetPosY,
z: v.targetPosZ,
track: fullTrack,
};
});
// 改进的方位角计算函数
const calculateBearing = (x1, y1, x2, y2) => {
const deltaX = x2 - x1;
const deltaY = y2 - y1; // Y轴反向(之前的修正)

if (Math.abs(deltaX) < 1e-10 && Math.abs(deltaY) < 1e-10) {
return 0;
}
let bearing = Math.atan2(deltaX, deltaY);

// 确保角度在 0-2π 范围内
if (bearing < 0) {
bearing += 2 * Math.PI;
}

return bearing;
};
// 创建实时点
const pointEntity = new Cesium.Entity({
id: `${item.targetId}_point`,
type: "point",
position: new Cesium.CallbackProperty(() => {
return Cesium.Cartesian3.fromDegrees(item.x, item.y, item.z);
}, false),
billboard: {
image: dd,
width: 50,
height: 50,
scale: 0.5,
rotation: new Cesium.CallbackProperty(() => {
// 获取轨迹中的最后一个有方向信息的点
const track = item.track;
if (!track || track.length < 2) return 0;

// 使用倒数第二个点的heading(这是从倒数第二个点到最后一个点的方向)
const secondLastPoint = track[track.length - 2];
const heading = secondLastPoint.heading;

if (heading === undefined || heading === null) return 0;
// 根据您的图标方向调整,可能需要以下调整之一:
// 选项1:直接使用计算的heading
return heading;
}, false),
verticalOrigin: Cesium.VerticalOrigin.CENTER,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
},
properties: {
type: "point",
},
});
`

The current effect is like this,Normally, the direction of the icon should face towards the bottom right

Image

Contributor guide

Open the contributing guide

Research direction

Start with the Cesium.Entity billboard configuration, especially the CallbackProperty used for rotation, and trace how item.track and its heading values are produced. Reproduce the supplied trajectory and verify that the real-time icon follows the final trajectory segment, including the expected bottom-right direction.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.