同一坐标系中,由任意两点计算地图旋转角度

时间:2022-04-14 10:25:03

 

同一坐标系中,由任意两点计算地图旋转角度

                                            ----原创文章,转载请注明出处,谢谢

一、引言

在各种GIS/GPS应用中,地图旋转是不可或缺的一部分,尤其明显的是用在实时导航,对象跟踪等应用方面。用来计算地图旋转时偏转角的坐标点有动态和静态两种之分。动态在这里指的是在已知当前点的情况下,下一点的具体位置是不确定的;而静态指的是下一点的具体位置是确定的。动态的应用我们常见到的是GPS导航、游戏中的赛车(多赛道、可转弯等)以及调度等中的实时地图旋转,而静态更常见的是作为一种功能的演示,如模拟导航,模拟赛车等。地图旋转只有在同一坐标系中进行才有意义,地图旋转角度的计算才有依据,本文主要着重点在于如何由前后两点计算地图旋转角度,同时主要考虑动态的方式,静态方式的旋转地图原理是一样的,就不分开介绍了。

二、约定和术语

²      参考坐标系:本文所依据的坐标系为北京54下的依据高斯克吕格投影所建立的坐标系,即高斯平面坐标系,它的图像如图:

同一坐标系中,由任意两点计算地图旋转角度
X
代表为正北方向,Y代表正东方向,为了使y值都为正,将纵坐标轴西移500km

²      正切函数是直角三角形中,对边与邻边的比值。放在直角坐标系中(如图)即 tanθ=y/x

其中tanθ的定义域为(-∏/2,+∏/2),值域为(-,+)
同一坐标系中,由任意两点计算地图旋转角度

²         偏转角:约定偏转角为北偏东的角度,将地图按照偏转角进行旋转后将始终朝着运动方向行驶。在高斯平面坐标系中,正北即为X轴,正东即为Y轴,所以tanθ还是为y/x,只是角度的位置有了变化,如图所示。
同一坐标系中,由任意两点计算地图旋转角度

²         反正切:函数y=tanx的反函数叫做反正切函数,记做:y=arctanx.
定义域:R;值域:(-π/2,π/2)
三、计算偏转角

假设存在一起始点pntBegin,并且存在一个原点为pntBegin的平面坐标系,同时约定要旋转的角度为rotateAngle,则下一点pntDest根据方位有几种情况,其示意图如下,我们可以分类进行讨论:

同一坐标系中,由任意两点计算地图旋转角度

l       pntDest.x1>=pntBegin.x0,则该点在第一和第四象限,具体对应点为pntDest(1)pntDest(4),分别对应的北偏东角度为α(1)和α(4),根据Y值的不同,我们又可以分两种情况,

n       若pntDest.y>=pntBegin.y://在第一象限
rotateAngle=arctan2(fabs(p0.x-p1.x),fabs(p0.y-p1.y));

n       若pntDest.y<pntBegin.y://在第四象限
rotateAngle=arctan2(fabs(p0.x-p1.x),fabs(p0.y-p1.y));

rotateAngle=∏-rotateAngle;

l       pntDest.x1<pntBegin.x0,则该点在第二和第三象限,具体对应点为pntDest(2)pntDest(3),分别对应的北偏东角度为α(2)和α(3),根据Y值的不同,分两种情况进行讨论,

n       若pntDest.y>=pntBegin.y://在第二象限
rotateAngle=arctan2(fabs(p0.x-p1.x),fabs(p0.y-p1.y));
rotateAngle= 2*∏-rotateAngle;

n       若pntDest.y<pntBegin.y://在第三象限
rotateAngle=arctan2(fabs(p0.x-p1.x),fabs(p0.y-p1.y));

rotateAngle=∏+rotateAngle;

四、在超图平台中实现
:开发语言为VC6,平台为eSuperMap;

代码如下:

 1 同一坐标系中,由任意两点计算地图旋转角度
 2 同一坐标系中,由任意两点计算地图旋转角度 void  CCarNaviView::RotateMap(CPoint pntBegin,CPoint pntNext)
 3 同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度 {    
 4同一坐标系中,由任意两点计算地图旋转角度    //计算旋转角度
 5同一坐标系中,由任意两点计算地图旋转角度    double dAngle=CalculateRotateAngle(pntBegin,pntNext);
 6同一坐标系中,由任意两点计算地图旋转角度    //地图旋转
 7同一坐标系中,由任意两点计算地图旋转角度    m_MapWnd.GetDrawParam()->SetMapRotationAngle( dAngle );
 8同一坐标系中,由任意两点计算地图旋转角度    m_MapWnd.Refresh();
 9同一坐标系中,由任意两点计算地图旋转角度}

10 同一坐标系中,由任意两点计算地图旋转角度
11 同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度 /// \brief 由前后两点计算当前地图偏转角并进行地图旋转
12同一坐标系中,由任意两点计算地图旋转角度/// \param pntbegin 起始点
13同一坐标系中,由任意两点计算地图旋转角度/// \param pntbegin 下一点
14同一坐标系中,由任意两点计算地图旋转角度/// \return 地图要旋转的角度(北偏东)
15同一坐标系中,由任意两点计算地图旋转角度/// \remark 为适应习惯用法,点坐标的表示方法为cpoint(x,y),如pntbegin(x,y)代表的含义为:
16同一坐标系中,由任意两点计算地图旋转角度///          x->正东,即为高斯投影中的Y,y->正北,代表高斯投影中的x

17 同一坐标系中,由任意两点计算地图旋转角度double  CCarNaviView::CalculateRotateAngle(CPoint pntBegin,CPoint pntNext)
18 同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度 {
19同一坐标系中,由任意两点计算地图旋转角度    CPoint pntFirst(pntBegin);
20同一坐标系中,由任意两点计算地图旋转角度    CPoint pntSecond(pntNext);
21同一坐标系中,由任意两点计算地图旋转角度    
22同一坐标系中,由任意两点计算地图旋转角度    double dRotateAngle = atan2(fabs(pntBegin.x-pntNext.x),fabs(pntBegin.y-pntNext.y));
23同一坐标系中,由任意两点计算地图旋转角度    
24同一坐标系中,由任意两点计算地图旋转角度    //如果下一点的横坐标大于前一点(在第一和第四象限)
25同一坐标系中,由任意两点计算地图旋转角度    if (pntNext.x>=pntFirst.x)
26同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度    {
27同一坐标系中,由任意两点计算地图旋转角度        //在第一象限(0<=dRotateAngle<=90)
28同一坐标系中,由任意两点计算地图旋转角度        if (pntNext.y>=pntFirst.y)
29同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度        {
30同一坐标系中,由任意两点计算地图旋转角度            //不做任何处理
31同一坐标系中,由任意两点计算地图旋转角度            dRotateAngle=dRotateAngle;
32同一坐标系中,由任意两点计算地图旋转角度        }

33同一坐标系中,由任意两点计算地图旋转角度        else
34同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度        {
35同一坐标系中,由任意两点计算地图旋转角度            dRotateAngle=PI-dRotateAngle;
36同一坐标系中,由任意两点计算地图旋转角度        }

37同一坐标系中,由任意两点计算地图旋转角度    }

38同一坐标系中,由任意两点计算地图旋转角度    else//(在第二和第三象限)
39同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度    {
40同一坐标系中,由任意两点计算地图旋转角度        //第二象限
41同一坐标系中,由任意两点计算地图旋转角度        if (pntNext.y>=pntFirst.y)
42同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度        {
43同一坐标系中,由任意两点计算地图旋转角度            dRotateAngle=2*PI-dRotateAngle;
44同一坐标系中,由任意两点计算地图旋转角度        }

45同一坐标系中,由任意两点计算地图旋转角度        else//第三象限
46同一坐标系中,由任意两点计算地图旋转角度同一坐标系中,由任意两点计算地图旋转角度        {
47同一坐标系中,由任意两点计算地图旋转角度            dRotateAngle=PI+dRotateAngle;
48同一坐标系中,由任意两点计算地图旋转角度        }

49同一坐标系中,由任意两点计算地图旋转角度    }

50同一坐标系中,由任意两点计算地图旋转角度    return dRotateAngle;
51同一坐标系中,由任意两点计算地图旋转角度}



五、结束语

整个计算过程并不复杂,甚至相当简单,重要的是要理解这个过程。各个开发平台也许有些出入,但是原理都应该相似,所以思路我相信是可以移植的。同时关于在下一点在坐标系上的情况我也已经考虑进去了,这里就不再说明了。同时,欢迎各位多提宝贵意见,集思广益,共同学习。