scala實現球面插值(Slerp)
一、球面插值
球面插值的原理大概就如下圖所示,大致理解就是計算球面角度的佔比,計算公式不是太複雜,如下所示:
當角度無限接近於0的時候,這個時候球面插值就演變為線性插值
下面用scala對球面插值進行一個簡單的實現:
class Slerp4scala[T <: Double](start: Vector[T], end: Vector[T], t: Double, omiga: Double) {
def this() = this(Vector(), Vector(), 0, 0)
def slerp(): Unit = {
if (start.size < 1) throw new Exception("Please fill your Array.")
if (t > 1 || t < 0) throw new Exception("Interpolator point error, its range is in " +
"[0, 1].")
val divisor = math.sin(omiga)
val p1 = math.sin((1 - t) * omiga) / divisor
val p2 = math.sin(t * omiga) / divisor
start.map(_ * p1).zip(end.map(_ * p2)).map(k => k._1 + k._2)
}
}
專案本意是要實現地球座標的球面插值,因為做過資料稀疏化的資料的距離都很大,不能近似的認為是線性插值(誤差較大),但是在求地球的omiga的時候,感覺實現起來還是有點麻煩,於是就找到了第三方的這個庫geotools,之前用的地理圖形操作都是採用的jts的包,這次對geotools又有了一個新的認識。下面是對Geotools的認識。
二、Geotools
高興的是在這個工具集中有很多的工具類,失望的我好像沒有發現計算omiga的介面,但是發現了一個計算路徑中平分點的api,雖然不能有效的解決我的問題,但也算是失之東隅收之桑榆吧,下面將測試程式碼貼出來:
"Geotools " should "be success " in{
val geoToolsTest = new GeodeticCalculator()
geoToolsTest.setStartingGeographicPoint(0, 0)
geoToolsTest.setDestinationGeographicPoint(60, 0)
assert(geoToolsTest.getAzimuth > 0)
// 取路徑上的幾個平均分段點
println(geoToolsTest.getGeodeticPath(5))
// 計算航向(與正北方向的夾角)
println(geoToolsTest.getAzimuth)
}
執行結果:
[Point2D.Double[0.0, 0.0], Point2D.Double[10.000000000000002, 0.0], Point2D.Double[20.000000000000004, 0.0], Point2D.Double[29.999999999999996, 0.0], Point2D.Double[40.00000000000001, 0.0], Point2D.Double[50.00000000000001, 0.0], Point2D.Double[59.99999999999999, 0.0]]
90.0
由於我用的是本地模式(本地代理上網sbt實在是有點慢),先下載geotools的java包,在SourceForge上面,最新版本好像已經是20了,這裡廢話就不多說了。
最後
回到最開始的問題,其實計算經緯度的球面插值,最為核心的就是將經緯度轉化為球面座標,然後根據球面插值的公式進行插值計算,計算出的插值點也為球面座標,然後再將球面座標轉換為通用的經緯度即可。
相關文章
- NOISEDIFFUSION: 改進基於擴散模型的球面線性插值模型
- 連續插值,用forall實現。
- 牛頓插值 C++ 和 Matlab實現C++Matlab
- Scala Essentials: 字串內插字串
- 數值分析Python實現系列—— 一、拉格朗日插值法Python
- SCSS #{} 插值CSS
- 實驗二 插值方法(android)Android
- 二、插值操作
- MATLAB插值Matlab
- MATLAB一維插值和二維插值 比較Matlab
- 【java】【插值查詢】Java
- 求插值係數
- 插值技術研究
- Scala實現乘法口訣
- 用Scala macros實現DCIMacROS
- 數值計算 插值與擬合
- c#-string 插值C#
- 拉格朗日插值
- 用Scala和Akka實現DDD
- 插值查詢演算法演算法
- Swift 5 字串插值之美Swift字串
- Swift 5 字串插值-簡介Swift字串
- 插值演算法總結演算法
- CoffeeScript攻略3.8:字串插值字串
- 2.Vue插值表示式Vue
- scala中的匿名子類實現
- 插值查詢的簡單理解
- MemoryCache 的原生插值方式淺談
- vue.js插值與表示式Vue.js
- 影象縮放--插值法(opencv,原理)OpenCV
- Qt自定義動畫插值函式QT動畫函式
- 查詢演算法__插值查詢演算法
- 常用演算法 插值演算法演算法
- Vue 模板語法第一式 —— 插值Vue
- 層次分析法 插值與擬合
- 拉格朗日插值學習筆記筆記
- 使用陣列實現環形佇列Scala版本陣列佇列
- Twitter開源其Scala最佳實踐Effective Scala