Для 2D-векторов способ, указанный в принятом ответе и других, не учитывает ориентацию (знак) угла (angle(M,N)
совпадает с angle(N,M)
) и возвращает правильное значение только для угла между 0
и pi
.
Используйте функцию atan2
, чтобы получить ориентированный угол и правильное значение (по модулю 2pi
).
angle <- function(M,N){
acos( sum(M*N) / ( sqrt(sum(M*M)) * sqrt(sum(N*N)) ) )
}
angle2 <- function(M,N){
atan2(N[2],N[1]) - atan2(M[2],M[1])
}
Убедитесь, что angle2
дает правильное значение:
> theta <- seq(-2*pi, 2*pi, length.out=10)
> O <- c(1,0)
> test1 <- sapply(theta, function(theta) angle(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test1 %% (2*pi), theta %% (2*pi))
[1] "Mean relative difference: 1"
> test2 <- sapply(theta, function(theta) angle2(M=O, N=c(cos(theta),sin(theta))))
> all.equal(test2 %% (2*pi), theta %% (2*pi))
[1] TRUE
Он определяет выражение assert ( something ), которое ничего не делает.
Предположительно, используемая среда не поддерживает инструкцию ANSI C assert , либо программист не знал того факта, что его можно отключить, определив NDEBUG.
Чтобы расширить то, что говорит bdonlan , причина того, что макрос не раскрывается пустым, заключается в том, что если это так, то что-то вроде:
assert(something) // oops, missed the semi-colon
assert(another_thing);
будет компилироваться в режиме выпуска, но не в режиме отладки. Причина, по которой это ((void) 0)
, а не просто 0
, состоит в том, чтобы предотвратить предупреждения «оператор без эффекта» (или как там их называет MSVC).
Чтобы добавить, это определение assert в newlib , когда NDEBUG
определен как директива препроцессора. Newlib - это библиотека C с открытым исходным кодом, которая используется в Cygwin и встроенных системах.
Из руководства assert в newlib :
Макрос определен, чтобы разрешить вам отключать все использования assert в время компиляции, определив
NDEBUG
как переменную препроцессора. Если вы сделаете это, the assert macro expands to(void(0))