2012-03-20 66 views
3

我想顺时针或逆时针旋转一个对象。几个整数(从0到7)表示物体正在寻找的方向(例如左,上,上,右,右,...)。向对象的当前方向添加+1将顺时针旋转,减1则逆时针旋转。确定转弯的方向?

如果我想让对象转向某个方向(=整数),我该如何确定必要的最小匝数?

目前我使用这种思维方式:

int minimumRequiredTurns = min(abs(currentDirection.intvalue - goalDirection.intvalue), 
         8 - abs(currentDirection.intvalue - goalDirection.intvalue)); 

是否有可能做到这一点没有min声明?

+0

8个方向代表什么? '(左,上,右,...)“ - 这意味着只有四个方向。请澄清 – WeaselFox 2012-03-20 14:43:01

+0

不应该是int minimumRequiredTurns = min(abs(currentDirection.intvalue-goalDirection.intvalue),8 - abs(currentDirection.intvalue-goalDirection.intvalue));' – tafa 2012-03-20 14:50:35

+0

你是对的,tafa。狡猾的狐狸,它实际上是左,上,上,挺,右,......)。 – Fatso 2012-03-20 14:54:00

回答

2

我觉得

(1-(abs(abs(currentDirection.intvalue - goalDirection.intvalue)/(n/2)-1)))*(n/2)

应该做的伎俩,其中n可能方向的数量。

为了让整只计算变换这

(n/2)-abs(abs(currentDirection.intvalue - goalDirection.intvalue)-(n/2))

说明:使用帽子函数生成的地图:

0 -> 0 
1 -> 1 
2 -> 2 
3 -> 3 
4 -> 4 
5 -> 3 
6 -> 2 
7 -> 1 
+0

将其编辑为符合OP – Azrael3000 2012-03-20 15:18:15

+0

+1的符号大大改进。 – Caleb 2012-03-20 15:19:12

+1

如果任何人有同样的想法,我不想变慢:) Thx – Azrael3000 2012-03-20 15:20:13

2

如果你真的不喜欢“分钟”,你可以使用查找表。

int minRequiredTurns[8][8] = { 
    0, 1, 2, 3, 4, 3, 2, 1, 
    1, 0, 1, 2, 3, 4, 3, 2, 
    2, 1, 0, 1, 2, 3, 4, 3, 
    /* and so on... */ 
}; 
+0

这个问题是,如果我添加子方向,表将是无用的。 – Fatso 2012-03-20 14:55:00

+0

@Korion:说实话,目前的解决方案也很好。 – hugomg 2012-03-20 16:19:53

1

首先,力产生积极的影响,那么力介于0和N/2之间(0和4)

N=8 
diff = (new-old+N)%N; 
turns = diff - (diff>N/2 ? N/2 : 0) 
+2

这足以让OP运行尖叫成'min'的怀抱:-) – 2012-03-20 14:53:28

+0

这很好,谢谢! – Fatso 2012-03-20 17:08:17

1
int N = 8, turns = abs(current-goal); 
if (turns > N/2) turns = N-turns; 

但我不明白你为什么不想分钟语句...

+0

也许这是一个有点人为的设计,但是你可以想象必须在一些不支持分支的非常有限的设备上实现这一点,并且你只能使用算术,或者出于性能原因需要避免分支的地方。 – gcbenison 2012-03-21 04:45:52

+0

当然这有效,斯马林诺夫,但它不完全是我以后。我希望沿着Azrael的回答或gcbenison的回答。算术,尽可能短。 – Fatso 2012-03-21 07:38:56

+1

@Korion我的不好,我不知何故完全通过你的问题的相关部分。 – 2012-03-21 12:28:49

2

几乎可以肯定,一个更好的设计是将使用向量来表示的方向;将“方向”视为一对数字(x,y),以便x代表水平方向,y代表垂直方向。

因此(1,0)将代表面向右方; (0,1)将代表朝上; (-1, 0)将面临左侧; (1,1)会朝右上方;等


然后,你可以使用普通的基于矢量的解决问题的方法:拿你面对的方向,你想要的方向去面对,并采取两个cross-product

 
result = x1y2 - x2y1 

如果结果为正,逆时针旋转;如果结果为负数,则顺时针旋转(由于定义了交叉产品的right-hand rule,因此这样工作)

请注意,这种方法泛泛地允许任意方向,而不仅仅是水平/垂直/对角线。

1

没有min,没有abs,一个表情,没有划分:

turns = ((((goalDirection + 8 - currentDirection) % 8) + 4) % 8) - 4 

它是如何工作:最里面的表达式(goalDirection + 8 - currentDirection)是AShelley给出相同;顺时针方向所需的圈数。最外层的表达式将其转换为[-4 .. + 3]中的等价值。

+0

令人惊叹!唯一的问题是结果可能是负面的,所以无论如何你需要'abs'。目前我很确定它的工作原理......再次感谢!当我确定它有效时,你会得到最好的回答。 – Fatso 2012-03-21 07:21:01