关于球面坐标中要素的方向问题

      这两天要在一个三维场景中实现GPS定位的小模块。本来以为会很简单,但是写的过程中发现问题并没有想象中那么简单。最近老在学习,没有什么东西可在博客上写的,就凑合写点吧。

      主要的目的为:将某一个移动GPS的运行轨迹在三维场景中实时展现,并以第一人称视角跟踪。

      模块的核心部分大概是这样的:

       1 捕获GPS传过来的数据,分解出位置坐标等信息,名称定为p1。

       2 通过坐标在【系统】的三维场景中定位,得到场景中的屏幕坐标,利用该屏幕坐标求出该位置在场景中的地面高度

       3 利用ORACLE数据库的空间分析能力缓冲查询p1点附近一定距离内的所有道路。并求出距离最近的那条道路,名称定  为line。

       4 求出p1点在道路线line的垂足u1。

       5 假设之前捕获的那个点为p0,在道路上的垂足为u0,那么用u0,u1两点可以求出道路线在该段的倾斜度。

       6 将该倾斜度转化的与正北方向的夹角。

       7 在p1点出创建一个标志对象,并让视角飞向该对象,视角位置为与道路线平行。

        其他部分都比较简单,在第5部分卡了一个早上。测试不出问题。知道肯定哪个算法出错了。部分代码如下

  

 

ContractedBlock.gif ExpandedBlockStart.gif 获取角度
 1 private double GetYaw(double x0,double y0,double x1,double y1)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 3            //以前一个垂足点作为基点构造新的坐标系统
 4            double x=x1-x0;
 5            double y=y1-y0;
 6            double yaw=0;
 7            if (x==0 && y==0)
 8                yaw = preYaw;//preYaw为道路前一段的角度
 9            else if (x == 0)
10ExpandedSubBlockStart.gifContractedSubBlock.gif            {
11                if (y > 0)
12                    yaw = 90;//12点位置
13                else 
14                    yaw =270;//6点位置
15            }

16            else if (y == 0)
17ExpandedSubBlockStart.gifContractedSubBlock.gif            {
18                if (x > 0)   //9点位置
19                    yaw = 180;
20                else
21                    yaw = 0//3点位置
22            }

23            else
24ExpandedSubBlockStart.gifContractedSubBlock.gif            {
25                yaw = 180 * Math.Atan(y / x) / 3.14;
26                int qdt = GetQuadrant(x, y);
27                switch (qdt)
28ExpandedSubBlockStart.gifContractedSubBlock.gif                {
29                    case 1://第一象限
30                        yaw = yaw; 
31                        break;
32                    case 2://第二象限
33                        yaw += 180
34                        break;
35                    case 3://第三象限
36                        yaw += 180;
37                        break;
38                    case 4://第四象限
39                        yaw += 360
40                        break;
41                    default:
42                        break;
43                }

44            }

45
46            return yaw; 
47             
48        }

49        //得到该点所在的象限
50        private int GetQuadrant(double x, double y)
51ExpandedBlockStart.gifContractedBlock.gif        {
52            int rst = 0;
53            if (x > 0 && y > 0)
54                rst = 1;
55            else if (x > 0 && y < 0)
56                rst = 4;
57            else if (x < 0 && y > 0)
58                rst = 2;
59            else
60                rst = 3;
61            return rst;
62        }

         测试了1个消失也没有发现破绽,最后在上厕所的时候终于想到问题所在。首先因为数据局限在局部分析,我就采用了类似与平面坐标系统的做法。因为我们要求的只是个与指北方向的夹角,所以完全可以忽略那点误差。但是在坐标系统上我却想当然的忽略了 X,Y方向上的变性,由于在数值上X(经度)的值域为[0 -360],而Y[纬度]却是[90S 90N],地球的投影椭圆可以近似看成一个圆,X,Y上的长度一样,但是他们在数值上的值域缺不统一,所以这个坐标系统是非数值与角度变化率不是1:1

。讲到这里问题就非常清楚了,可能咋一看,是个很小的问题,但是习惯了平面坐标,偶然涉及到球面坐标就不小心弄错。最后,上面的代码只要加一句(x /= 2)纠正变形就可以了。     

 

      

 

    

转载于:https://www.cnblogs.com/gis_sky/archive/2009/11/27/1611694.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值