Я хочу создать приложение, которое использует сенсор телефона для вращения 3D-объекта в OpenGL. Но я хочу, чтобы ось Z была заблокирована, поэтому я хочу в основном применить 2D-вращение к моей модели.
Чтобы построить 2D-вращение из трехмерной матрицы, полученной из SensorManager.getRotationMatrixFromVector()
Я строю матрицу вращения для каждой осикак объяснено на рисунке:
Я хочу применить 2D матрицу вращения, которая будет R=Ry*Rx
, но это, похоже, не работает. Но применение R=Rz*Ry
работает как положено. Я предполагаю, что значения Rx
неверны.
Чтобы построить матрицы Rz
, Ry
, Rx
, я искал значения, используемые SensorManager.getOrientation()
для вычисления углов:
values[0] = (float) Math.atan2(R[1], R[4]);
values[1] = (float) Math.asin(-R[7]);
values[2] = (float) Math.atan2(-R[6], R[8]);
Итак, вот как я строю матрицы для каждой оси:
private val degConst = 180/Math.PI
private var mTempRotationMatrix = MatrixCalculations.createUnit(3)
override fun onSensorChanged(event: SensorEvent?) {
val sensor = event?.sensor ?: return
when (sensor.type) {
Sensor.TYPE_ROTATION_VECTOR -> {
SensorManager.getRotationMatrixFromVector(mTempRotationMatrix, event.values)
val zSinAlpha = mTempRotationMatrix[1]
val zCosAlpha = mTempRotationMatrix[4]
val ySinAlpha = -mTempRotationMatrix[6]
val yCosAlpha = mTempRotationMatrix[8]
val xSinAlpha = -mTempRotationMatrix[7]
val xCosAlpha = mTempRotationMatrix[4]
val rx = MatrixCalculations.createUnit(3)
val ry = MatrixCalculations.createUnit(3)
val rz = MatrixCalculations.createUnit(3)
val sina = xSinAlpha
val cosa = xCosAlpha
val sinb = ySinAlpha
val cosb = yCosAlpha
val siny = zSinAlpha
val cosy = zCosAlpha
rx[4] = cosa
rx[5] = -sina
rx[7] = sina
rx[8] = cosa
ry[0] = cosb
ry[2] = sinb
ry[6] = -sinb
ry[8] = cosb
rz[0] = cosy
rz[1] = -siny
rz[3] = siny
rz[4] = cosy
val ryx = MatrixCalculations.multiply(ry, rx)
mTempRotationMatrix = ryx
MatrixCalculations.copy(mTempRotationMatrix, mRenderer.rotationMatrix)
LOG.info("product: [" + mRenderer.rotationMatrix.joinToString(" ") + "]")
val orientation = FloatArray(3)
SensorManager.getOrientation(mTempRotationMatrix, orientation)
LOG.info("yaw: " + orientation[0] * degConst + "\n\tpitch: " + orientation[1] * degConst + "\n\troll: " + orientation[2] * degConst)
}
Вопрос в том, что я делаю неправильно и какие значения использовать для матрицы Rx
. Моя математика применяется к этой проблеме сломана? Также было бы интересно узнать, как значение event.values[3]
связано с построением матрицы вращения в SensorManager.getRotationMatrixFromVector()
.
В теории операция R=Ry*Rx
должна дать мне правильное вращение, но это не так.