简体   繁体   English

如何使用360度旋转获得正确的2D方向

[英]How to get the right direction in 2D using 360 rotation

I'm trying to get the nearest direction for an object to spin too or shortest. 我正在尝试为物体旋转得最近或最短的方向。

Basically the idea is that the object is given a desired direction and must spin towards that direction the shortest way possible. 基本上,该想法是为对象指定所需的方向,并且必须以尽可能短的方式朝该方向旋转。

I have the following code: 我有以下代码:

rotationChangeAmount = (this.getDirection(getRotation(), mDestinationRotation)) ? -rotationChangeAmount : rotationChangeAmount;

Using the following function: 使用以下功能:

private boolean getDirection(double targetRotation, double value)
{
    //Max 100 max (360)
    //Target 60
    //Value 30
    //Value - Max > Target - Max

    if(Math.abs(targetRotation - 360.0) > Math.abs(value - 360.0))
    {
        return false;
    }
    return true;
}

Thinking about this logically, if the distance between the value and the target Rotation is greater than 180, clockwise, if it is less, counter clockwise, assuming target < original. 从逻辑上考虑此问题,如果值和目标Rotation之间的距离大于180,则顺时针旋转;如果较小,则逆时针旋转,并假设目标<原始。

Say I have 270 initially and I want 180. abs (270-180) is 90, so I will rotate counter clockwise, which we know from a cursory look is correct. 假设我最初有270个,而我想有180个。abs(270-180)是90,所以我将逆时针旋转,从粗略的外观上我们知道这是正确的。

If I have 270 initially and I want 45, then (270-45) = 225, so I would rotate clockwise (which we also know is correct) 135 degrees 如果我最初有270个并且想要45个,那么(270-45)= 225,所以我将顺时针旋转(我们也知道这是正确的)135度

If I have 45 initially and I want 300, then abs (45 - 300) = 255, so I would rotate counter clockwise (since initial is less than target) 105 degrees. 如果我最初有45个并且想要300,那么abs(45-300)= 255,因此我将逆时针旋转(因为初始值小于目标值)105度。

Finally, if I have 45 initially and I want 90, then abs (45 - 90) = 45 and I would rotate clockwise 45 degrees. 最后,如果我最初有45个并且想要90,那么abs(45-90)= 45并且我将顺时针旋转45度。

So, to build your function on this logic: 因此,要根据以下逻辑构建函数:

 private double getChange(double target, double original){
      if (target < original){
           if (Math.abs(original - target) > 180)
               return Math.abs((360 - original) + target);
           else
               return (-1 * Math.abs(target - original);
      }
      else{
           if (Math.abs(target - original) > 180)
               return Math.abs( (360 - target) + original);
           else
               return (-1 * Math.abs(original - target);
      }
 }

Done via TDD: 通过TDD完成:

package rotation;

import static org.junit.Assert.*;
import org.junit.Test;

public class RotationTest {
    public enum Direction { RIGHT, LEFT, EITHER }

    public Direction getDirection(double current, double target) {
        validate(current);
        validate(target);
        double alwaysLarger = current < target ? (current + 360) : current;
        double gap = alwaysLarger - target;
        return gap > 180
            ? Direction.RIGHT
            : (gap == 180 ? Direction.EITHER : Direction.LEFT);
    }

    private void validate(double degrees) {
        if (degrees < 0 || degrees > 360) {
            throw new IllegalStateException();
        }
    }

    @Test
    public void test() {
        assertEquals(Direction.LEFT, getDirection(90, 1));
        assertEquals(Direction.LEFT, getDirection(90, 359));
        assertEquals(Direction.LEFT, getDirection(90, 271));
        assertEquals(Direction.EITHER, getDirection(90, 270));
        assertEquals(Direction.RIGHT, getDirection(90, 269));
        assertEquals(Direction.RIGHT, getDirection(90, 180));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM