Как рассчитать двухмерное вращение из трехмерной матрицы, полученной от датчика TYPE_ROTATION_VECTOR (чтобы заблокировать одноосное вращение) - PullRequest
0 голосов
/ 31 октября 2019

Я хочу создать приложение, которое использует сенсор телефона для вращения 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 должна дать мне правильное вращение, но это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...