Создание поворота для аналогового таймера в openGL
Я пишу игру OpenGL es (2.0) для Android.
У меня есть текстурированный четырехугольник, вот так:
Перед тем, как войти на каждый уровень, я устанавливаю значение, которое представляет собой количество секунд, которое этот таймер должен повернуть. Я тогда просто выясняю, на сколько градусов вращаться каждую секунду. Вот так:
AngleToRotate = 360/numberOfSeconds;
Поэтому, когда я хочу повернуть, я делаю что-то вроде этого: (псевдокод)
if (countOneSecond()){
rotateTimer(AngleToRotate)
}
Так что.... если я хочу, чтобы это заняло 60 секунд, я говорю
AngleToRotate = 360/60 (AngleToRotate = 6)
Каждые секунды он поворачивается на 6 градусов, поэтому полный оборот происходит за 1 минуту.
проблема
Проблема в том, что если я хочу повернуть на величину, в которой угол не дает целого числа, я столкнусь с проблемами, скажем, 80 секунд:
AngleToRotate = 360/80 (AngleToRotate = 6) = 4.5
Поэтому он вращается только на 4.
Резюме
Итак, возможно ли повернуть квад на долю угла? Или есть еще одна хитрость, чтобы таймер совершил полный оборот за указанное количество секунд?
Код
Вот мой метод вращения:
public void rotate(float x, float y, float angle){
//Convert OpenGL co-ordinates into screen coordinates
//xPlotRight and xPlotLeft are defined, I have removed them from here as they
//aren't relevant to this question
//Center of quad (Along the x)
centreX = xPlotLeft + ((xPlotRight-xPlotLeft)/2);
//Center of quad (Along the y)
centreY = yPlotBottom + ((yPlotTop-yPlotBottom)/2);
//Rotate the quad
Matrix.setIdentityM(mRotationMatrix, 0);
Matrix.translateM(mRotationMatrix, 0, centreX, centreY, 0f);
Matrix.rotateM(mRotationMatrix, 0, -angle, 0, 0, 0.1f);
Matrix.translateM(mRotationMatrix, 0, -centreX, -centreY, 0f);
}
1 ответ
OpenGL ES 2.0 на самом деле не имеет концепции углов. Мы не видим этого в коде, который вы разместили, но кто-то строит матрицу вращения под углом, который, скорее всего, заканчивается mRotationMatrix
переменная на основе кода, который вы показываете. Практически любая используемая вами матрица преобразования будет иметь элементы с плавающей запятой и, следовательно, может представлять повороты для произвольных углов с точностью до плавающей запятой.
Если AngleToRotate
в настоящее время типа int
, вам нужно сделать это float
, Точно так же, если rotateTimer
в настоящее время имеет int
аргумент, измените тип аргумента на float
, Затем проверьте код rotateTimer
и убедитесь, что он проходит по углу как float, если вызывает дополнительные методы. В какой-то момент вы должны прийти к коду, который строит матрицу вращения, которая, скорее всего, преобразует угол из градусов в радианы, вычисляя cos
а также sin
угла, и заполните матрицу вращения этими значениями.
Я бы порекомендовал сохранить все ваши углы в радианах, но это скорее предложение стиля.