【问题标题】:Compass - Track number of full 360 degree rotations指南针 - 跟踪完整 360 度旋转的次数
【发布时间】:2017-06-12 00:31:00
【问题描述】:

假设一个人正在使用这个指南针,从 90 度开始,他们开始顺时针或逆时针旋转。计算他们完成了多少次完整的 360 度旋转的最佳方法是什么?假设它们从头到尾仅顺时针或逆时针旋转。

我不断提出解决方案,例如,如果起始方位角为 90 度,我会在传感器数据发生变化时继续检查下一个方位角,如果它始终沿一个方向移动,我知道它们正在旋转。如果他们继续向那个方向旋转并使其回到 90 度,那算作一次旋转。我的方法看起来非常复杂且效率低下,我很难想出更好的方法。

在这种情况下,我预计会有多个完整的轮换。

如果有任何帮助,我将不胜感激。谢谢!

我找到了this 相关答案,并试图为此整理一个代码示例。如果有人已经做过类似的事情,请发布!

@Override
public void onSensorChanged(SensorEvent event)
{
    switch(event.sensor.getType())
    {
        case Sensor.TYPE_GRAVITY:
        {
            mValuesAccelerometer = lowPass(event.values.clone(), mValuesAccelerometer);
            break;
        }
        case Sensor.TYPE_MAGNETIC_FIELD:
        {
            mValuesMagneticField = lowPass(event.values.clone(), mValuesMagneticField);
            break;
        }
    }

    boolean success = SensorManager.getRotationMatrix(
            mMatrixR,
            mMatrixI,
            mValuesAccelerometer,
            mValuesMagneticField);

    if (success)
    {
        SensorManager.getOrientation(mMatrixR, mMatrixValues);

        float azimuth = toDegrees(mMatrixValues[0]);
        float pitch = toDegrees(mMatrixValues[1]);
        float roll = toDegrees(mMatrixValues[2]);

        if (azimuth < 0.0d)
        {
            //The bearing in degrees
            azimuth += 360.0d;
        }
    }
}

【问题讨论】:

    标签: android android-sensors compass-geolocation


    【解决方案1】:

    如果您确定它们只会朝一个方向移动,那么为了优化您的代码,您可以设置度数检查点,而不是持续监控它们是否仍在朝正确的方向移动。

    这是一个粗略的算法

    //You noted 90 degree as starting point
    // checkpoint 1 will be 180 keep it as a boolean 
    // now you've reached 180 if the meter gets to 180 before going to next checkpoint 
    // which is 270 then make 180 false. it means they turned back. 
    // if they make it to 270 then wait for 0 degrees and do the same. 
    // if they make it back to 90 like that. You got a rotation and hopefully 
    // a bit of complexity is reduced as you're just checking for 4 checkpoints 
    

    目前我手头没有任何代码。

    【讨论】:

      【解决方案2】:

      这是一个读数溢出的跟踪问题。您需要跟踪最后一次读数,并希望用户在每次读数之间不超过半圈......(由于奈奎斯特定理)

      这是基本的伪代码。

      var totalChange = 0;
      var lastAzimuth = -1000;
      
      function CountTurns(az)
      {
        if (az > 180) az -= 360;   // do this if your azimuth is always positive i.e. 0-360.
      
        if (lastAzimuth == -1000)
        {
          lastAzimuth = az;
        }
      
        diff = az - lastAzimuth;
        if (diff > 180)
           diff -= 360;
        if (diff < -180)
           diff += 360;
      
        lastAzimuth = az;
        totalChange += diff;
        return totalChange / 360;
      }
      

      【讨论】:

      • 是的。没有多余的嵌入式代码。我会相信我的生活。
      【解决方案3】:

      创建 3 个整数

      int rotationCount=0
      int currentDegrees=0
      int previousDegrees=89
      

      不是 Java 程序员,所以我不知道您如何处理 onSensorChanged 事件,但基本上是在 while 循环内执行检查

      while (currentDegrees + 90 < 360)
      {
          if (currentDegrees + 90 == 0) 
          {
              if (previousDegrees == 359) 
              {
                  rotationCount = rotationCount + 1
              }
          }
          else if (currentDegrees + 90 == 359) 
          {
              if (previousDegrees == 0) 
              {
                  rotationCount = rotationCount - 1
              }  
          }
          previousDegrees = currentDegrees + 90
      }
      

      对语法感到抱歉,这只是一个示例。

      【讨论】:

        【解决方案4】:

        想象一下我会说什么,你肯定会很快达到你的目标。 因为您不需要考虑完整的 360 度,但您可以采取其中的一半并利用符号差异来发挥您的优势。

        看看这张图:

        我们有一个分为两侧(左右)的圆圈。

        左侧为负 180 度。 (西区)。

        右侧将取正 180 度。 (东区)。

        当前位置将始终为 0 作为(北),正 180 作为(南)。

        如果指南针变为正数(表示方向正确)

        然后每回合加+1。

        如果指南针变为负数(意味着向左方向)。

        然后每回合减去-1

        如果指南针命中 OR 为 0,则它是当前位置 (NORTH)。

        如果罗盘命中 OR 为 90,则为(东)。

        如果指南针命中 OR 为 180,则为(南)

        如果指南针命中 OR 为 -90,则为(西)。

        结果是,每当这个人往东走时,计数器会加 +1 直到达到 180,然后它会从正变为负,每转一圈都会减去 -1,直到达到 0。那将是一个完整的 360 度旋转。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-10
          相关资源
          最近更新 更多