19 votos

Promedio de cuaterniones

Dados múltiples cuaterniones que representan orientaciones, y quiero promediarlos. Cada uno tiene un peso diferente, y todos suman uno.

¿Cómo puedo obtener la media de ellos? La simple multiplicación por pesos y suma no funcionará, ya que no tiene en cuenta que (qw, qx, qy, qz) = (-qw, -qx, -qy, -qz)..

0 votos

Google da es.wikipedia.org/wiki/interpolación_de_cuaterniones_generalizada Alguien que sepa más podrá ampliar la información.

0 votos

@PeterTaylor esa página de Wikipedia ya no existe, pero probablemente la que buscas es es.wikipedia.org/wiki/Slerp . Véase también mi nueva respuesta más abajo para más información.

0 votos

Para tratar específicamente la cuestión de la doble cubierta (es decir ${\bf q}$ y $-{\bf q}$ que representa la misma rotación), consulte esta pregunta y respuesta: math.stackexchange.com/preguntas/3888504 . Para saber cómo aplicar esto al promedio de cuaterniones, consulta mi respuesta a tu pregunta: math.stackexchange.com/a/3435296/365886

11voto

Luke Hutchison Puntos 106

Promedio de pares de cuaterniones

Si está intentando promediar sólo dos cuaterniones, puede utilizar la interpolación de cuaterniones ( slerp ) con un factor de interpolación de 0,5 para encontrar el "punto medio rotacional" entre los dos cuaterniones.

(Nótese que la Ec. 19 del trabajo de Markley et al. citado más abajo también da una solución directa / de forma cerrada para la media de dos cuaterniones. Esto puede o no dar el mismo resultado que slerp con un factor de interpolación de 0,5, no lo he mirado de cerca).

Promedio de más de dos cuaterniones

Existen al menos dos métodos para promediar más de dos cuaterniones.

1. Promedio directo (rápido/aproximado)

Si los cuaterniones representan rotaciones similares, y los cuaterniones están normalizados, y se ha aplicado una corrección para el "problema de la doble cobertura", entonces se pueden promediar directamente los cuaterniones y luego normalizar de nuevo el resultado, tratándolos como vectores de 4 dimensiones, para producir un cuaternión que represente una rotación aproximadamente media.

El problema de la doble cobertura es cuando $q$ y $-q \,$ representan la misma rotación, como señalaba el cartel original. Este problema puede resolverse negando algún subconjunto de los cuaterniones para garantizar que el producto punto de cualquier par de cuaterniones es positivo (o, por ejemplo, negativo).

Tenga en cuenta que cuanto más disímiles sean los cuaterniones involucrados, más inexacto será este método, ya que esto es sólo una aproximación al método de eigendecomposition -- por lo que sólo desea promediar juntos cuaterniones que ya son bastante similares en términos de las rotaciones que representan.

He medido este método 2,56 veces más rápido que el de eigendecomposición.

(La sintaxis utilizada corresponde a la biblioteca Java JOML)

public static Quaterniond averageApprox(Quaterniond[] quats, double[] weights) {
    if (weights != null && quats.length != weights.length) {
        throw new IllegalArgumentException("Args are of different length");
    }
    Quaterniond qAvg = new Quaterniond(0.0, 0.0, 0.0, 0.0);
    for (int i = 0; i < quats.length; i++) {
        Quaterniond q = quats[i];
        double weight = weights == null ? 1.0 : weights[i];

        // Correct for double cover, by ensuring that dot product
        // of quats[i] and quats[0] is positive
        if (i > 0 && quats[i].dot(quats[0]) < 0.0) {
            weight = -weight;
        }

        qAvg.add(weight * q.x, weight * q.y, weight * q.z, weight * q.w);
    }
    return qAvg.normalize();
}

2. Eigendecomposición de la suma de productos exteriores (método de máxima verosimilitud)

Este método se basa en Markley y otros, Averaging Quaternions, Journal of Guidance, Control, and Dynamics, 30(4):1193-1196, junio de 2007 ecuaciones (12) y (13). Los autores demostraron que la solución es única y que corresponde a un criterio de máxima verosimilitud. ( aplicación de tbirdal de este mismo algoritmo, además de algunas variantes más potentes, se enlazaron desde un par de respuestas más).

(La sintaxis utilizada corresponde a la biblioteca Java JOML y a la biblioteca Apache Commons Math Linear Algebra)

public static Quaterniond average(Quaterniond[] quats, double[] weights) {
    if (weights != null && quats.length != weights.length) {
        throw new IllegalArgumentException("Args are of different length");
    }
    RealMatrix accum = MatrixUtils.createRealMatrix(4, 4);
    for (int i = 0; i < quats.length; i++) {
        Quaterniond q = quats[i];
        double weight = weights == null ? 1.0 : weights[i];
        RealVector qVec = MatrixUtils.createRealVector(
                new double[] { q.x, q.y, q.z, q.w });
        RealMatrix qOuterProdWeighted = qVec.outerProduct(qVec)
                .scalarMultiply(weight);
        accum = accum.add(qOuterProdWeighted);
    }
    EigenDecomposition eigDecomp = new EigenDecomposition(accum);
    double[] ev0 = eigDecomp.getEigenvector(0).toArray();
    return new Quaterniond(ev0[0], ev0[1], ev0[2], ev0[3]).normalize();
}

3voto

bw. Puntos 21

Supongo que estás pensando en cuaterniones unitarios y que los utilizas para representar rotaciones. Si es así, aquí tiene un papel sobre el tema relacionado de las medias y promedios en el grupo de rotación. Aunque puede que no sea una lectura muy fácil si no entiendes la notación.

Salvo eso, esto es lo que podría intentar: Elige una forma canónica para tus cuaterniones. A continuación, convertir cada uno a la forma canónica y, finalmente, realizar su combinación lineal ponderada.

0 votos

La solución promediando formas canónicas se parece a la solución de jonathon a su pregunta : stackoverflow.com/a/12439567/1200764

3voto

adrelino Puntos 1

Hay un informe técnico de 2001 que afirma que la media es en realidad una aproximación bastante buena, siempre que los cuaterniones estén próximos entre sí. (para el caso de -q=q, podrías simplemente voltear los que apuntan en la otra dirección pre multiplicándolos por -1, para que todos los cuaterniones involucrados vivan en la misma media esfera.

En este documento de 2007 que implica el uso de un SVD.

3 votos

Hay un implementación en matlab Así como un implementación en c que ambos se basan en el método del último artículo. Como referencia, me gustaría señalar también este debate sobre el mismo tema.

0 votos

Para más información sobre la aplicación, véase esta pregunta de stackoverflow

1voto

lakumg Puntos 2334

Esta respuesta de Gouda da el funcionamiento del Implementación en Matlab de Tolga Birdal, que está bien comentada.

1voto

Tolga Birdal Puntos 126

Ahora proporciono la media estándar y ponderada, así como $L_p$ mediana de cuaterniones en: http://tbirdal.blogspot.com/

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X