RecyclerView
предназначен для расширения, поэтому нет необходимости подклассифицировать LayoutManager
(поскольку droidev предложил ) просто для выполнения прокрутки.
Вместо этого, просто создайте SmoothScroller
с предпочтением SNAP_TO_START
:
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
};
Теперь вы устанавливаете положение, в котором вы хотите прокрутить страницу:
smoothScroller.setTargetPosition(position);
и передать этот SmoothScroller в LayoutManager:
layoutManager.startSmoothScroll(smoothScroller);
Согласно странице 5 в этого PDF , sum(a*b)
- это команда R, чтобы найти скалярное произведение векторов a
и b
, а sqrt(sum(a * a))
- это команда R, чтобы найти норма вектора a
, а acos(x)
- команда R для арккосинуса. Отсюда следует, что R-код для расчета угла между двумя векторами равен
theta <- acos( sum(a*b) / ( sqrt(sum(a * a)) * sqrt(sum(b * b)) ) )
Для 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
Другое решение: корреляция между двумя векторами равна косинусу угла между двумя векторами.
, поэтому угол можно вычислить с помощью acos(cor(u,v))
# example u(1,2,0) ; v(0,2,1)
cor(c(1,2),c(2,1))
theta = acos(cor(c(1,2),c(2,1)))
Я думаю, что вам нужен внутренний продукт. Для двух векторов v,u
(в R^n
или любых других пространствах внутренних произведений) <v,u>/|v||u|= cos(alpha)
. (где alpha
- это угол между векторами)
, более подробно см .:
Вы должны использовать скалярное произведение. Скажем, у вас есть V ₁ = ( x ₁, y ₁, z ₁) и V ₂ = ( x ₂, y ₂, z ₂), то скалярное произведение, которое я обозначу через V ₁ · V ₂, рассчитывается как
V ₁ · V ₂ = x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂ = | V ₁ | · | V ₂ | · Cos ( θ );
Это означает, что указанная слева сумма равна произведению абсолютных значений векторов на косинус угла между векторами. абсолютное значение векторов V ₁ и V ₂ рассчитывается как
| V ₁ | = √ ( x ₁² + y ₁² + z ₁²) и
| V ₂ | = √ ( x ₂² + y ₂² + z ₂²),
Итак, если вы переставите первое уравнение выше, Вы получите
cos ( θ ) = ( x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂) ÷ (| V ₁ | · | V ₂ | ),
и вам просто нужна функция arccos (или обратный косинус), примененная к cos ( θ ), чтобы получить угол.
В зависимости от функции arccos угол может быть в градусах или радианах.
(Для двумерных векторов, просто забудьте про z -координаты и сделайте те же вычисления.)
Удачи,
Джон Донер
Мой ответ состоит из двух частей. Часть 1 является математикой - чтобы дать ясность всем читателям потока и сделать понятным следующий код R. Часть 2 - программирование на R.
Точечное произведение двух векторов x и y можно определить как:
где || x || является евклидовой нормой (также известной как норма L 2 ) вектора x .
Управляя определением точечного произведения, мы можем получить:
где тета - угол между векторами x и y выражено в радианах. Обратите внимание, что тета может принимать значение, лежащее на отрезке от 0 до pi.
Решая для самой тета, мы получаем:
Чтобы перевести математику в R-код, нам нужно уметь выполнять два матричных (векторных) вычисления; скалярное произведение и евклидова норма (которая является специфическим типом нормы, известной как норма L 2 ). Нам также нужно знать R-эквивалент обратной косинус-функции, cos -1 sup>.
Начиная сверху. Ссылаясь на ?"%*%"
, скалярное произведение (также называемое внутренним произведением) может быть вычислено с использованием оператора %*%
. Со ссылкой на ?norm
функция norm()
(базовый пакет) возвращает a норму вектора. Здесь интересующей нормой является норма L 2 или, на языке справочной документации R, «спектральная» или «2» -норма. Это означает, что аргумент type
функции norm()
должен быть установлен равным "2"
. Наконец, функция обратного косинуса в R представлена функцией acos()
.
Решение
Оборудованный как математикой, так и соответствующими функциями R, можно создать функцию-прототип (то есть не производственный стандарт) - используя функции базового пакета - как показано ниже. Если приведенная выше информация имеет смысл, то последующая функция angle()
должна быть понятной без дальнейших комментариев.
angle <- function(x,y){
dot.prod <- x%*%y
norm.x <- norm(x,type="2")
norm.y <- norm(y,type="2")
theta <- acos(dot.prod / (norm.x * norm.y))
as.numeric(theta)
}
Проверка функции
Проверка, чтобы убедиться, что функция работает. Пусть x = (2,1) и y = (1,2). Продукт точек между x и y равен 4. Евклидова норма x равна sqrt (5). Евклидова норма y также является квадратом (5). cos theta = 4/5. Тета составляет примерно 0,643 радиана.
x <- as.matrix(c(2,1))
y <- as.matrix(c(1,2))
angle(t(x),y) # Use of transpose to make vectors (matrices) conformable.
[1] 0.6435011
Надеюсь, это поможет!