zoukankan      html  css  js  c++  java
  • 【WP 8.1开发】电子罗盘

    罗盘,估计也不用我过多介绍,学过初中物理的都知道,不管是指南针,还是指北针,其本质就是用来辨别方向的。

    操作电子罗盘伟感器也不复杂,主要就是两个角度:

    1、当前方向与磁北的夹角;

    2、当前方向与地北的夹角。

    同时,我们也了解到,地理北极与地磁北极并不是重合的,存在地偏角。在读取电子罗盘数据时,可以优先考虑读取与地北极的夹角,如果读不到地北极的夹角,再读取磁北极的夹角数据。

    CompassReading类(位于Windows.Devices.Sensors命名空间)封装了从电子罗盘所读到的数据。

    1、HeadingMagneticNorth属性:获取当前方向与磁北的夹角度数。

    2、HeadingTrueNorth属性:该属性获取的是真北夹角,即地理夹角。我们注意到它的类型为double?,即Nullable<double>,表明这个数值有可能为null,也就是说有可能获取不到地北夹角的值。在使用时,我们可以先判断地北角是否为null,如不为null就用这个值;如果为null就用磁北角的值。

    3、HeadingAccuracy属性:表示罗盘读数的准确性,如果读数精度较高,其返回High。我们的应用程序可以在合适的时候检查这个属性是否为High,如果不是,可以考虑提示用户校准罗盘。

    提到校准,不得不说一下的是,校准罗盘是不需要系统提示,应用也可以不提示。只是考虑到用户体验的问题,可以提示用户校准。校准方法很简单,不管你是使用WP自带的地图应用,还是其他第三方应用,或者你自己开发的应用。只要在使用到罗盘的地方,你拿着手机,在空中做几次“8”字形来回移动就可以了,不需要等待提示,只要在用到罗盘的地方就可以随时校准

    电子罗盘的API封装在Windows.Devices.Sensors.Compass类中,WP API中的所有传感器调用都很简单,首先获取到某个传感器类的实例,一般通过GetDefault方法(静态方法)就能返回,然后设置读取的时间间隔,以毫秒为单位,如果你希望每秒读一次数据,就把ReportInterval设置为1000,但是,这个时间间隔不能小于MinimumReportInterval属性指定的值,这个要注意,设置为20毫秒以上的间隔,效果都不错了,当然这要看你使用的实际情况了。

    最后处理ReadingChanged事件,当有新的数据读到时,会引发该事件,并把新读到的数据传递给该事件,我们就可以从事件参数中获取最新的读数。

    好了,理论永远都是抽象的,下面给大家看一下我做的一个简陋指南针,确实很简,希望大家莫笑,因为本人较菜,所以连主页上的罗盘也是用XAML直接画的。

    先上一个效果图。

    看吧,简陋吧,没办法,人穷就是这样,要简食素衣。指南针背景我是用几个圈圈画的,指示方向的指针是用Path元素画的。

    原理是这样的:

    根据电子罗盘读到的角度,对红色的指针对象进行旋转变换——就是用RotateTransform类来旋转。但要注意旋转的角度。比如,我当前方向是20度,即东北偏北方向,那么,要怎么设置角度才能保证红色的指针始终指向南方呢。

    我们知道,夹角是以正北为参考的,如果要使指针指向南方,一种方法是将罗盘读到的角度加上180,因为南北的夹角正好是180度(平角);另一种方法是,让指针的初始位置向下,即指向正南方,我就是用这个方法的。如图。

    不管是指向北方还是南方(上北下南),都可以按相同的角度来旋转,因为它们的夹角正好是180。

    于是,第二个问题产生了——要旋转多少度才合适?我们上面举例说当前方向为20度,参照标准是北极,也就是说此时我们的手机已经偏向20度方向,如果把指针旋转20度,那么指针相对于屏幕,偏转的角度就是40度了,本来就偏了20度,你再转20度,就番倍了,显然这样不妥,我们必须把这个角度差抵消掉。

    也就是说,如果我当前方向是20度,那么指针的旋转变换应为-20度,这样才能把偏差的角度补平,不然的话,你试试就知道了,如果不抵消的话,指针会越走越偏。

    还有一种方法就是用360度作为被减数,如360 - 20 = 340度,-20度和340度虽然计算方向不同,但它们的位置是相同的。因此两种方法都可以。比如读数是80度,可以把指针旋转-80度,也可以旋转360 - 80度。

            async void _compass_ReadingChanged ( Compass sender, CompassReadingChangedEventArgs args )
            {
                var res = args.Reading;
                // 如果地北极的偏角值不可用,则使用磁北极角度
                double val = res.HeadingTrueNorth ?? res.HeadingMagneticNorth;
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                    () =>
                    {
                        // 如果精度较高,则停止校准
                        if (isChecking && res.HeadingAccuracy == MagnetometerAccuracy.High)
                        {
                            fly.Hide();
                            isChecking = false;
                        }
    
                        // 旋转的方向是罗盘角度的负值
                        rotatTransform.Angle = -val;
                        Display(val);
                    });
            }

    Display方法是我自定义的方法,用来判断读数所指的方向,并在页面上以文本的方式显示。比如,读数为0,就是“正北”,读数为180度,为“正南”等。

            /// <summary>
            /// 显示方位
            /// </summary>
            private void Display ( double v )
            {
                string d = "";
                int ind = Convert.ToInt32(v);
                if (ind == 0 || ind == 360)
                {
                    d = "正北";
                }
                else if (ind == 90)
                {
                    d = "正东";
                }
                else if (ind == 180)
                {
                    d = "正南";
                }
                else if (ind == 270)
                {
                    d = "正西";
                }
                else if (ind > 0 && ind < 90)
                {
                    d = "东北";
                }
                else if (ind > 90 && ind < 180)
                {
                    d = "东南";
                }
                else if (ind > 180 && ind < 270)
                {
                    d = "西南";
                }
                else if (ind > 270 && ind < 360)
                {
                    d = "西北";
                }
                tbW.Text = string.Format("{0}°({1})", ind, d);
            }

    以上所列是重点的代码片段,其他代码大家可以参考我上传的示例源代码。

    下载地址:http://files.cnblogs.com/tcjiaan/CompassApp.zip

  • 相关阅读:
    Asp.net全局资源文件( App_GlobalResources)和本地资源文件(App_LocalResources)
    基于bootstrap3.3.4的简单框架搭建(左侧导航收起滚动)
    jquery file upload + asp.net 异步多文件上传
    写给若干年后的自己
    There is already an open DataReader associated with this Connection which must be closed first EF
    我,一个传统男人的22岁
    错误 137 (net::ERR_NAME_RESOLUTION_FAILED):未知错误
    Android APK反编译详解(附图)
    string的连接字符串方法及效率
    腾讯QQ API接口调用 之QQ状态查询
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/3951092.html
Copyright © 2011-2022 走看看