2012-03-20 2 views
3

Я хочу повернуть объект по часовой стрелке или против часовой стрелки. Пара целых чисел (от 0 до> 7) представляет направление, к которому стремится объект (например, левый, левый, вверх, вертикальный, правый, ...). Добавление +1 к текущему направлению объекта поворачивает его по часовой стрелке, вычитая -1, поворачивает его против часовой стрелки.Определение направления поворота?

Если я хочу, чтобы объект повернулся в определенном направлении (= целое число), как мне определить минимальное количество оборотов?

В настоящее время я использую этот способ мышления:

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

Можно ли это сделать без min заявления?

+0

Что означают 8 направлений? '(left, up, right, ...)' - это подразумевает только четыре направления. пожалуйста, уточните – WeaselFox

+0

не должно быть int 'minimumRequiredTurns = min (abs (currentDirection.intvalue - goalDirection.intvalue), 8 - abs (currentDirection.intvalue - goalDirection.intvalue));' – tafa

+0

вы правы, tafa. WeaselFox, это на самом деле левый, левый, вверх, вертикальный, правый, ...). – Fatso

ответ

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

+0

+1 Улучшено. – Caleb

+1

Я не хотел быть медленным, если у кого-то была такая же идея :) Thx – Azrael3000

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

+0

@Korion: Честно говоря, текущее решение тоже jst. – hugomg

1

Во-первых, принуждать положительное значение, то сила от 0 до N/2 (0 и 4):

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

Этого достаточно, чтобы заставить OP запустить крик в объятия «мин» :-) –

+0

Это отлично работает, спасибо! – Fatso

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

Но я не понимаю, почему вы не хотите, мин-о ...

+0

Возможно, это немного надуманно, но вы можете себе представить, как это реализовать на каком-то действительно ограниченном устройстве, которое не поддерживает ветвление, и вы можете использовать только арифметику или где вам действительно нужно избегать ветвления по соображениям производительности. – gcbenison

+0

Уверен, что это работает, smarinov, но это не совсем то, что мне нужно. Я хотел что-то в ответ на ответ Азраила или ответ gcbenison. Просто арифметика, как можно короче. – Fatso

+1

@Korion. Мой плохой, я как-то полностью прошел соответствующую часть вашего вопроса. –

2

Почти наверняка, гораздо лучше дизайн будет векторов используют для представления направлений; обрабатывать «направление» как пару чисел (x,y) так, чтобы x представляло собой горизонтальное направление, y представляет собой вертикальное.

So (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

Смежные вопросы