当前位置:网站首页>Cesium parabolic equation
Cesium parabolic equation
2022-06-12 17:30:00 【GhostPaints】
There are two functional modules in the company's project , Import trade and export trade . Of a global nature , After you get two coordinates , You need a parabolic line connecting the two points . Sometimes a line needs to cross half the earth , As a result, some threads will penetrate the ground .
Because it uses path, With line animation , Not used polyline. If it is to use polyline Words , There will be no ground penetration , It will be close to the ground .
The original project treatment method was : Two coordinate points are known , Given the set animation time . Use SampledPositionProperty Method to find the middle point . Then the three points form a line .
// 86400 Total time ,43200 It's the middle moment
var startTime = viewer.clock.startTime;
var midTime = Cesium.JulianDate.addSeconds(startTime, 43200, new Cesium.JulianDate());
var stopTime = Cesium.JulianDate.addSeconds(startTime, 86400, new Cesium.JulianDate());
// From the coordinates of the place to the coordinates of the end point , In the middle is the midpoint
var property = new Cesium.SampledPositionProperty();
var startPosition = Cesium.Cartesian3.fromDegrees( Starting point coordinates , Starting point coordinates , 0);
property.addSample(startTime, startPosition);
var stopPosition = Cesium.Cartesian3.fromDegrees( End coordinates , End coordinates , 0);
property.addSample(stopTime, stopPosition);
// Finding the midpoint , And give the midpoint a height
var midPoint = Cesium.Cartographic.fromCartesian(property.getValue(midTime));
midPoint.height = Cesium.Math.nextRandomNumber() * 100000 + 900000;
var midPosition = viewer.scene.globe.ellipsoid.cartographicToCartesian(midPoint, new Cesium.Cartesian3());
// Three coordinate points
const resultproperty = new Cesium.SampledPositionProperty();
resultproperty .addSample(startTime, startPosition);
resultproperty .addSample(midTime, midPosition);
resultproperty .addSample(stopTime, stopPosition);
// Add to entity in
const entity = viewer.entities.add({
position: resultproperty,
..... Other configuration ......
})
// Set the interpolation method
entity.position.setInterpolationOptions({
interpolationDegree : 5,
interpolationAlgorithm : Cesium.LagrangePolynomialApproximation
});Specify the travel animation of two points , When the animation time is half , The position obtained is the midpoint of the two line segments . Then draw a parabola from three points . But this parabola will have the problem of passing through the ground .

The original optimal result should be all emanating from one point , However, some lines do not start correctly , It looks like it started from the ground . This method is only applicable to certain areas , When the distance between two points may span half the earth , Not very good .
So consider using the second method , I found a parabolic equation on the Internet , Draw a parabola based on this equation .
Drawing method receives Starting point , End point coordinates , Height , Number of coordinate points Four parameters .
1. First judge that the longitude spacing is large , Or the latitudinal distance is large
The span of latitude is the absolute value obtained by directly subtracting the northern and southern hemispheres . The longitude of the eastern and western hemispheres is a little troublesome , It is also subtracting to find the absolute value , If this absolute value is greater than 180, It means that it is closer from the other direction , The span is calculated as 360- The absolute value of longitude . If you don't switch , The drawn lines will make more detours .
2. According to the number of coordinate points indicated , Calculate the longitude change and latitude change
So here's the code :
// Parabolic equation { pt1: {lon: 114.302312702, lat: 30.598026044}, pt2: {lon: 114.302312702, lat: 30.598026044}, height: height, num: 100 }
function parabolaEquation(options) {
// equation y=-(4h/L^2)*x^2+h h: Vertex height L: Larger horizontal and vertical spacing
// Set the minimum height
const h = options.height && options.height > 5000 ? options.height : 5000;
let latLength = Math.abs(options.pt1.lat - options.pt2.lat);
let lonLength = Math.abs(options.pt1.lon - options.pt2.lon);
if (lonLength > 180) {
lonLength = 360 - lonLength;
}
const L = lonLength > latLength ? lonLength : latLength;
const result = [];
// Set the minimum number of coordinate points 50 individual
const num = options.num && options.num > 50 ? options.num : 50;
let dlt = L / num;
if (lonLength > latLength) {// With lon Benchmarking
const delLat = (options.pt2.lat - options.pt1.lat) / num;
// Increase from west to east to positive number . From east to west, it increases to a negative number
if (Math.abs(options.pt1.lon - options.pt2.lon) > 180 || options.pt1.lon - options.pt2.lon > 0) {
dlt = -dlt;
}
for (let i = 0; i < num; i++) {
const tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
const lon = options.pt1.lon + dlt * i;
const lat = options.pt1.lat + delLat * i;
result.push([lon, lat, tempH]);
}
} else {// With lat Benchmarking
let delLon = (options.pt2.lon - options.pt1.lon) / num;
if (options.pt1.lat - options.pt2.lat > 0) {
dlt = -dlt;
}
for (let i = 0; i < num; i++) {
const tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
const lon = options.pt1.lon + delLon * i;
const lat = options.pt1.lat + dlt * i;
result.push([lon, lat, tempH]);
}
}
// to ground
result.push([options.pt2.lon,options.pt2.lat,options.pt2.height || 0])
return result;
}If the number of coordinate points is transmitted by one 50 go in , The actual returned array is 51 individual . Every child of this array is an array , If drawn polyline You also need to traverse the expansion .
Finally, dynamic values are generated
// Dynamic path
const property = new Cesium.SampledPositionProperty();
const allTime = 86400;
const stepTime = 86400 / ( Number of coordinate points +1);
const startTime = viewer.clock.startTime;
const stopTime = Cesium.JulianDate.addSeconds(startTime, allTime, new Cesium.JulianDate());
for (let index = 0; index < positionsArr.length; index++) {
const point = positionsArr[index];
if (index === 0) {
property.addSample(startTime, Cesium.Cartesian3.fromDegrees( Starting point coordinates , Starting point coordinates , 0));
}else if (index === positionsArr.length - 1) {
property.addSample(stopTime, Cesium.Cartesian3.fromDegrees( End coordinates , End coordinates , 0));
}else {
property.addSample(Cesium.JulianDate.addSeconds(startTime, (index)*stepTime, new Cesium.JulianDate()),Cesium.Cartesian3.fromDegrees(point[0],point[1],point[2]))
}
}Replace the original one resultproperty That's it .
The renderings are as follows
There's no more floor dressing , This is the import effect , The exchange between the starting point and the end point is the exit effect from the dispersion .
边栏推荐
- R语言使用ggplot2可视化dataframe数据中特定数据列的密度图(曲线)、并使用xlim参数指定X轴的范围
- 5-5配置Mysql复制 基于日志点的复制
- 邱盛昌:OPPO商业化数据体系建设实战
- Difference between big end mode and small end mode
- 5、Embedding
- "Upgrade strategy" of two new committers
- office应用程序无法正常启动0xc0000142
- Qiushengchang: Practice of oppo commercial data system construction
- ssm常用到的依赖
- (4) Golang operator
猜你喜欢

How to use the official documents of pytorch and torchvision

多种Qt的开发方式,你选择哪种?

Application case of smart micro 32-bit MCU for server application cooling control

全局锁、表锁、行锁

LCD参数解释及计算

Risc-v ide mounriver studio v1.60 update point introduction

Schrodinger's Japanese learning applet source code

Some minor problems and solutions encountered when using ubantu

How to view, modify, and delete SSH

内核中断整体流程图
随机推荐
The R language uses the tablestack function of epidisplay package to generate statistical analysis tables based on grouped variables (including descriptive statistical analysis, hypothesis test, diffe
Figma从入门到放弃
Nebula's practice of intelligent risk control in akulaku: training and deployment of graph model
R语言使用epiDisplay包的pyramid函数可视化金字塔图、基于已有的汇总数据(表格数据)可视化金字塔图
Use GCC's PGO (profile guided optimization) to optimize the entire system
《用户体验要素:以用户为中心的产品设计》笔记
MySQL事务简介、事务隔离级别
快速入门scrapy爬虫框架
错误记录:IllegalStateException: Optional int parameter ‘xxxx‘ is
String s = null ; String s = new String();String s =““ ;String s ;有什么区别?
Implementation of asynchronous query of Flink dimension table and troubleshooting
龙芯处理器内核中断讲解
Modify the configuration of the router connected to your computer. The website is 192.168.1.1
Feedback compilation
Saturated! Can't future programmers work anymore?
Memory control of node
新媒体运营素材网站分享,让你创作时事半功倍
5-5 configuring MySQL replication log point based replication
[BSP video tutorial] stm32h7 video tutorial Issue 8: the last issue of the MDK theme, the new generation of debugging technologies event recorder and RTT, and using stm32cubemx to generate project tem
力扣今日题926. 将字符串翻转到单调递增