354 lines
14 KiB
HTML
354 lines
14 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>计算通信方位角和大圆距离</title>
|
||
<!-- Bootstrap -->
|
||
<link href="https://cdn.gh.ink/assembly/bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet">
|
||
<!-- Favicon -->
|
||
<link rel="icon" href="https://2-cdn.ianxia.com/images/avatar/common.png" type="image/png">
|
||
<script src="https://cdn.gh.ink/js/vue/2.6.14/vue.min.js"></script>
|
||
<script>
|
||
function sgn(n) {
|
||
if (n > 0) {
|
||
return 1;
|
||
} else if (n < 0) {
|
||
return -1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
function fndeg(d, m, s) {
|
||
return d + sgn(d) * (m / 60 + s/ 3600);
|
||
}
|
||
|
||
function fnacs(x) {
|
||
return Math.PI / 2 - 2 * Math.atan(x / (1 + Math.sqrt(1 - x * x)));
|
||
}
|
||
|
||
function calc(tlongd, tlatd, rlongd, rlatd) {
|
||
let ro = 6370;
|
||
|
||
let gcdkm;
|
||
let btrd;
|
||
let brtd;
|
||
|
||
let r2d = 180 / Math.PI;
|
||
let d2r = Math.PI / 180;
|
||
|
||
let tlong = tlongd * d2r;
|
||
let tlat = tlatd * d2r;
|
||
let rlong = rlongd * d2r;
|
||
let rlat = rlatd * d2r;
|
||
|
||
if (tlong < 0) {
|
||
tlong = Math.PI * 2 + tlong;
|
||
}
|
||
if (rlong < 0) {
|
||
rlong = Math.PI * 2 + rlong;
|
||
}
|
||
|
||
let dlong = tlong - rlong;
|
||
if (Math.abs(dlong) > Math.PI) {
|
||
dlong = dlong - Math.PI * 2 * sgn(dlong);
|
||
}
|
||
|
||
let x = Math.sin(tlat) * Math.sin(rlat) + Math.cos(tlat) * Math.cos(rlat) * Math.cos(dlong);
|
||
let gcd = fnacs(x);
|
||
|
||
if (gcd < 0.0000001) {
|
||
gcd = 0.0000001;
|
||
}
|
||
|
||
if (Math.cos(tlat) - 0.0000001 <= 0) {
|
||
let btr;
|
||
if (tlat >= 0) {
|
||
btr = 0;
|
||
} else {
|
||
btr = Math.PI;
|
||
}
|
||
|
||
if (Math.cos(rlat) - 0.0000001 > 0) {
|
||
x = (Math.sin(tlat) - Math.sin(rlat) * Math.cos(gcd)) / (Math.cos(rlat) * Math.sin(gcd));
|
||
let brt = fnacs(x);
|
||
if (dlong < 0) {
|
||
brt = Math.PI * 2 - brt;
|
||
}
|
||
gcdkm = gcd * ro;
|
||
btrd = btr * r2d;
|
||
brtd = brt * r2d;
|
||
} else {
|
||
let brt;
|
||
if (rlat >= 0) {
|
||
brt = 0;
|
||
} else {
|
||
brt = Math.PI;
|
||
}
|
||
gcdkm = gcd * ro;
|
||
btrd = btr * r2d;
|
||
brtd = brt * r2d;
|
||
}
|
||
} else {
|
||
x = (Math.sin(rlat) - Math.sin(tlat) * Math.cos(gcd)) / (Math.cos(tlat) * Math.sin(gcd));
|
||
let btr = fnacs(x);
|
||
|
||
if (dlong > 0) {
|
||
btr = Math.PI * 2 - btr;
|
||
}
|
||
|
||
if (Math.cos(rlat) - 0.0000001 > 0) {
|
||
x = (Math.sin(tlat) - Math.sin(rlat) * Math.cos(gcd)) / (Math.cos(rlat) * Math.sin(gcd));
|
||
let brt = fnacs(x);
|
||
if (dlong < 0) {
|
||
brt = Math.PI * 2 - brt;
|
||
}
|
||
gcdkm = gcd * ro;
|
||
btrd = btr * r2d;
|
||
brtd = brt * r2d;
|
||
} else {
|
||
let brt;
|
||
if (rlat >= 0) {
|
||
brt = 0;
|
||
} else {
|
||
brt = Math.PI;
|
||
}
|
||
gcdkm = gcd * ro;
|
||
btrd = btr * r2d;
|
||
brtd = brt * r2d;
|
||
}
|
||
}
|
||
|
||
return [gcdkm, btrd, brtd];
|
||
}
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||
<a class="navbar-brand" href="https://tools.ianxia.com"><b>Ian</b>Tools</a>
|
||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||
<ul class="navbar-nav ml-auto">
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||
语言
|
||
</a>
|
||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||
<a class="dropdown-item" href="en.html"><b>English</b></a>
|
||
</div>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="https://www.ianxia.com">首页</a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="https://blog.ianxia.com">博客</a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="https://demo.ianxia.com">DEMO</a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a class="nav-link" href="https://adsb.ianxia.com">ADS-B</a>
|
||
</li>
|
||
<li class="nav-item active">
|
||
<a class="nav-link" href="../zh.html">小工具</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
<section>
|
||
<div class="jumbotron text-center mt-2">
|
||
<div class="container">
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<h1>计算通信方位角和大圆距离</h1>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section>
|
||
<div class="container">
|
||
<div class="row" id="app">
|
||
<div class="col-md-1"></div>
|
||
<div class="col-md-5">
|
||
<form class="form-horizontal" role="form">
|
||
<div class="form-inline">
|
||
<label><b>发信点经度</b> </label>
|
||
<input type="number" class="form-control" v-model="tlongdd" max="180" min="-180" placeholder="度" style="width:70px; height:30px;"> 度
|
||
<input type="number" class="form-control" v-model="tlongdm" max="60" min="-60" placeholder="分" style="width:70px; height:30px;"> 分
|
||
<input type="number" class="form-control" v-model="tlongds" max="60" min="-60" placeholder="秒" style="width:70px; height:30px;"> 秒
|
||
</div>
|
||
<div class="form-inline">
|
||
<label><b>发信点纬度</b> </label>
|
||
<input type="number" class="form-control" v-model="tlatdd" max="90" min="-90" placeholder="度" style="width:70px; height:30px;"> 度
|
||
<input type="number" class="form-control" v-model="tlatdm" max="60" min="-60" placeholder="分" style="width:70px; height:30px;"> 分
|
||
<input type="number" class="form-control" v-model="tlatds" max="60" min="-60" placeholder="秒" style="width:70px; height:30px;"> 秒
|
||
</div>
|
||
<div class="form-inline">
|
||
<label><b>收信点经度</b> </label>
|
||
<input type="number" class="form-control" v-model="rlongdd" max="180" min="-180" placeholder="度" style="width:70px; height:30px;"> 度
|
||
<input type="number" class="form-control" v-model="rlongdm" max="60" min="-60" placeholder="分" style="width:70px; height:30px;"> 分
|
||
<input type="number" class="form-control" v-model="rlongds" max="60" min="-60" placeholder="秒" style="width:70px; height:30px;"> 秒
|
||
</div>
|
||
<div class="form-inline">
|
||
<label><b>收信点纬度</b> </label>
|
||
<input type="number" class="form-control" v-model="rlatdd" max="90" min="-90" placeholder="度" style="width:70px; height:30px;"> 度
|
||
<input type="number" class="form-control" v-model="rlatdm" max="60" min="-60" placeholder="分" style="width:70px; height:30px;"> 分
|
||
<input type="number" class="form-control" v-model="rlatds" max="60" min="-60" placeholder="秒" style="width:70px; height:30px;"> 秒
|
||
</div>
|
||
</form>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<h5>计算结果:</h5>
|
||
<h5>大圆距离为{{gcdkm}}(km)</h5>
|
||
<h5>发信点对收信点的方位角为{{btrdd}}度{{btrdm}}分{{btrds}}秒</h5>
|
||
<h5>收信点对发信点的方位角为{{brtdd}}度{{brtdm}}分{{brtds}}秒</h5>
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<hr>
|
||
<h5>算法来源:《业余无线电通信》 童效勇BA1AA 陈方BA4RC 附录18</h5>
|
||
<h5>语言翻译:Bigsk (<a href="https://git.ghink.net/bigsk/commu_a_c" target="_blank">Git仓库</a>)</h5>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<hr>
|
||
<script>
|
||
function result(object) {
|
||
let tlongd = fndeg(parseInt(object.tlongdd), parseInt(object.tlongdm), parseInt(object.tlongds))
|
||
let tlatd = fndeg(parseInt(object.tlatdd), parseInt(object.tlatdm), parseInt(object.tlatds))
|
||
let rlongd = fndeg(parseInt(object.rlongdd), parseInt(object.rlongdm), parseInt(object.rlongds))
|
||
let rlatd = fndeg(parseInt(object.rlatdd), parseInt(object.rlatdm), parseInt(object.rlatds))
|
||
return calc(tlongd, tlatd, rlongd, rlatd)
|
||
}
|
||
|
||
new Vue({
|
||
el: '#app',
|
||
data: {
|
||
tlongdd: 103,
|
||
tlongdm: 45,
|
||
tlongds: 0,
|
||
tlatdd: 36,
|
||
tlatdm: 2,
|
||
tlatds: 0,
|
||
rlongdd: 121,
|
||
rlongdm: 29,
|
||
rlongds: 0,
|
||
rlatdd: 31,
|
||
rlatdm: 14,
|
||
rlatds: 0
|
||
},
|
||
computed: {
|
||
gcdkm: function () {
|
||
return result(this)[0]
|
||
},
|
||
btrdd: function () {
|
||
let d = Math.trunc(result(this)[1])
|
||
return d
|
||
},
|
||
btrdm: function () {
|
||
let d = Math.trunc(result(this)[1])
|
||
let m = Math.trunc((result(this)[1] - d) * 60)
|
||
return m
|
||
},
|
||
btrds: function () {
|
||
let d = Math.trunc(result(this)[1])
|
||
let m = Math.trunc((result(this)[1] - d) * 60)
|
||
let s = Math.trunc((result(this)[1] - d - m / 60) * 3600)
|
||
return s
|
||
},
|
||
brtdd: function () {
|
||
let d = Math.trunc(result(this)[2])
|
||
let m = Math.trunc((result(this)[2] - d) * 60)
|
||
return d
|
||
},
|
||
brtdm: function () {
|
||
let d = Math.trunc(result(this)[2])
|
||
let m = Math.trunc((result(this)[2] - d) * 60)
|
||
return m
|
||
},
|
||
brtds: function () {
|
||
let d = Math.trunc(result(this)[2])
|
||
let m = Math.trunc((result(this)[2] - d) * 60)
|
||
let s = Math.trunc((result(this)[2] - d - m / 60) * 3600)
|
||
return s
|
||
}
|
||
}
|
||
})
|
||
|
||
let date = new Date();
|
||
</script>
|
||
<footer class="text-center">
|
||
<div class="container">
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<p style="color: #516069"><strong>版权所有 © Ian Xia <script>document.write(date.getFullYear().toString());</script> 保留所有权利</strong></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||
<script src="https://cdn.gh.ink/js/jquery/jquery-3.6.0.min.js"></script>
|
||
<!-- Grey Filter Detector -->
|
||
<script>
|
||
$.ajax({
|
||
type: "GET",
|
||
url: "https://api.gh.ink/grey_filter",
|
||
dataType: "json",
|
||
success: function(data, textStatus){
|
||
for (let i=0;i<data["content"]["accurate_slot"].length;i++) {
|
||
// Accurate Slot
|
||
if (Date.now()/1000 >= data["content"]["accurate_slot"][i][0] && Date.now()/1000 <= data["content"]["accurate_slot"][i][1]) {
|
||
$("html").css({
|
||
'-webkit-filter': 'grayscale(100%)',
|
||
'-moz-filter': 'grayscale(100%)',
|
||
'-ms-filter': 'grayscale(100%)',
|
||
'-o-filter': 'grayscale(100%)',
|
||
'filter': 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)',
|
||
'_filter': 'none'
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
for (let i=0;i<data["content"]["day_slot"].length;i++) {
|
||
// Day Slot
|
||
let begin = new Date(
|
||
date.getFullYear().toString() + "-" +
|
||
data["content"]["day_slot"][i][0][0].toString() + "-" +
|
||
data["content"]["day_slot"][i][0][1].toString() + " " +
|
||
data["content"]["day_slot"][i][0][2].toString() + ":" +
|
||
data["content"]["day_slot"][i][0][3].toString() + ":" +
|
||
data["content"]["day_slot"][i][0][4].toString()
|
||
)
|
||
let end = new Date(
|
||
date.getFullYear().toString() + "-" +
|
||
data["content"]["day_slot"][i][1][0].toString() + "-" +
|
||
data["content"]["day_slot"][i][1][1].toString() + " " +
|
||
data["content"]["day_slot"][i][1][2].toString() + ":" +
|
||
data["content"]["day_slot"][i][1][3].toString() + ":" +
|
||
data["content"]["day_slot"][i][1][4].toString()
|
||
)
|
||
if (Date.now() >= begin.getTime() && Date.now() <= end.getTime()) {
|
||
$("html").css({
|
||
'-webkit-filter': 'grayscale(100%)',
|
||
'-moz-filter': 'grayscale(100%)',
|
||
'-ms-filter': 'grayscale(100%)',
|
||
'-o-filter': 'grayscale(100%)',
|
||
'filter': 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)',
|
||
'_filter': 'none'
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
||
<script src="https://cdn.gh.ink/js/popper/1.16.1/popper.min.js"></script>
|
||
<script src="https://cdn.gh.ink/assembly/bootstrap/4.6.1/js/bootstrap.min.js"></script>
|
||
</body>
|
||
</html> |