Rotación 3D usando aritmética de punto fijo: el objeto giratorio se está deformando (y encogiendo)

1

Tengo una placa FPGA (Virtex 5) para la cual he creado una GPU Wireframe con la capacidad de rotar un objeto de muestra utilizando una bola de seguimiento de 3 ejes. Además, he conectado la placa a un monitor de PC.

¿Inicialmente el objeto puede verse intacto (sin deformaciones)? Sin embargo, cuando comienzo a mover la bola de seguimiento, observo que el objeto comienza a deformarse y encogerse.

He intentado varios métodos para proporcionar inmunidad al problema, pero no puedo evitar que el objeto se deforme.

Principalmente, he tratado de multiplicar cada coordenada por un factor de corrección en la rotación, de modo que a medida que los puntos se contraen, multiplico por el factor de corrección (determinado por la distancia original al centro para cada punto dividido por la nueva distancia contraída) .

Con estos métodos implementados todavía no puedo evitar la deformación.

¿Hay alguna manera en el punto fijo para mantener intactas las coordenadas del objeto en la rotación?

    
pregunta Vahe

1 respuesta

6

Ahora que conoce el problema, puede formular una solución.

La aritmética de punto fijo es inexacta. Así es el punto flotante, por lo que generalmente no resuelve el problema, simplemente lo difiere. (En algunos aspectos, el IEE P754 estricto es una excepción a esto, ya que ciertas propiedades de las operaciones están garantizadas, pero no es una solución completa: lea algo del trabajo del Profesor Kahan para más ...)

Parece que está calculando iterativamente cada fotograma del fotograma anterior, de modo que se acumulan errores de redondeo. Además, si el objeto se está reduciendo constantemente, sugiere que está truncando en lugar de redondear.

Algunas técnicas comunes pueden ayudar aquí:

(1) El truncamiento en lugar del redondeo introduce un error sistemático que tiende a 0. Puede resolver esto al redondear correctamente en cualquier lugar que truncaría (reduzca un resultado amplio para que se ajuste a una palabra estrecha)

Ejemplo:

signal A,B,C   : unsigned(15 downto 0);
signal Product : unsigned(31 downto 0);
...
Product <= A * B;
C <= Product(31 downto 16);

Ha desechado los bits 15 a 0, o en promedio 0.5LSB de la salida C. Un cálculo correctamente redondeado usaría esta información (o al menos su LSB) para obtener Product(31 downto 16) o Product(31 downto 16) + 1 .

Por ejemplo

C <= Product(31 downto 16) + Product(15 downto 15);

Por lo tanto, el error máximo en cada operación se reduce a la mitad, y se distribuye a ambos lados de 0. Sin embargo, esto todavía puede dejar al objeto distorsionado al azar, aunque el crecimiento o la contracción aleatorios deben promediarse.

(2) Usa transformaciones conocidas para preservar invariantes. Por ejemplo, en lugar de calcular X, Y, Z iterativamente del paso anterior, calcule X e Y iterativamente, y Z de la ecuación R^2 = X^2 + Y^2 + Z^2 , como Z=sqrt(R^2 - X^2 - Y^2) para que los errores en X e Y puedan introducir pequeños errores en Z, pero se garantiza que el invariante (R) es correcto, preservando así el tamaño del objeto.

(3) Ampliando el comentario útil de Ignacio:

Mantener el objeto de muestra intacto.

En su lugar, haga un seguimiento de la rotación de un vector de unidad simple (longitud 1, cualquier orientación) y, una vez calculado, para el paso actual (conservando su invariante, es decir, R = 1 como en el paso 2), gire el objeto original por ese vector de unidad. Esto garantiza que cualquier error no persista más allá del marco actual.

    
respondido por el Brian Drummond

Lea otras preguntas en las etiquetas