scala实现球面插值(Slerp)

Posted 通凡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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了,这里废话就不多说了。

最后

回到最开始的问题,其实计算经纬度的球面插值,最为核心的就是将经纬度转化为球面坐标,然后根据球面插值的公式进行插值计算,计算出的插值点也为球面坐标,然后再将球面坐标转换为通用的经纬度即可。

以上是关于scala实现球面插值(Slerp)的主要内容,如果未能解决你的问题,请参考以下文章

声源定位 球面散乱数据插值方法/似然估计hybrid spherical interpolation/maximum likelihood (SI/ML) 麦克风阵列声源定位

计算球面上任意两点间的球面距离(C++实现)

PCL:投影滤波将点云投影至球面

已知球面经纬度求方位角和反方位角(awk一行代码实现)

PCL:RANSAC球面拟合

Unity怎么实现滚动球面