<!DOCTYPE html> <html lang="zh_CN"> <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.ghink.net/assembly/bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet"> <!-- Favicon --> <link rel="icon" href="https://cdn.ghink.net/image/avatar/Bigsk.png" type="image/png"> <script src="https://cdn.ghink.net/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_US.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_CN.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://gitea.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.ghink.net/js/jquery/jquery-3.6.0.min.js"></script> <!-- Grey Filter Detector --> <script> $.ajax({ type: "GET", url: "https://open.geh.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.ghink.net/js/popper/1.16.1/popper.min.js"></script> <script src="https://cdn.ghink.net/assembly/bootstrap/4.6.1/js/bootstrap.min.js"></script> </body> </html>