Ayuda con algoritmo de rotacion continua

EnZo

Buenas, estoy intentando hacer un jueguecito donde tengo que rotar un cubo de forma simultanea. Mirar la imagen:
http://s15.postimage.org/9jnxo407t/explicacion.gif

El punto rojo es el eje de rotacion del cubo/rectangulo. La linea discontinua sería el suelo.

Para hacer una rotacion "realista" hacia la derecha, la opcion correcta seria la tres. Donde X=1 Y=1. Hasta ahí bien. Una vez hecho el primer giro si queremos girar a la izquierda nos valdria el eje x=1,y=1.

Pero para hacer un giro de 360º hacia la derecha tendriamos la siguiente secuencia de ejes:
x=1 y=1
x=1 y=-1
x=-1 y=-1
x=-1 y=1

Mi problema es que estoy haciendolo en 3D tendre que meterle el eje Z y no se me ocurre una forma de colocar los ejes en funcion de a donde quiero girar sin tener que hacer 1232432 millones de switchs/ifs.

Espero que se haya entendido el problema, y gracias de antemano :)

elkaoD

No lo he entendido muy bien. ¿Puedes explicarlo de otra forma?

EnZo

Ok, lo explico de nuevo.

Quiero hacer algo parecido a este juego:
http://www.miniclip.com/games/bloxorz/es/
Es decir, emular los movimientos del cubo.

Vamos a plantearlo primero en 2D. He clasificado los ejes de rotacion de mi cubo así:
http://postimage.org/image/3ucr0unhj/
Esto se entiende supongo.

Entonces para hacer una rotacion del cubo de 360 grados con el efecto que tiene bloxorz sería con esta secuencia:
x=1 y=1
x=1 y=-1
x=-1 y=-1
x=-1 y=1

Que representada en dibujo es así:
http://postimage.org/image/d3exaywdj/

Si solo fuese en 2D cambiaria los 4 ejes en funcion de la rotacion que el cubo tenga. Pero que pasa si en el segundo caso de esta secuencia http://postimage.org/image/d3exaywdj/
en vez de girar hacia la derecha gira hacia atras o hacia adelante. Como vuelvo a reorganizar todos los ejes tras varios giros?

En 2D se puede girar a derecha o a izquierda. Pero si metemos otro eje podra girar adelante y atras. Entonces reorganizar los ejes de rotacion es un cacao que no se como resolver sin hacer infinitas comparaciones.

No se si se os ocurre algun algoritmo para realizar esto.

Si no se entiende intento explicarlo con un grafico en 3D.

elkaoD

No entiendo absolutamente nada xD

En primer lugar: Bloxorz hace eso con animaciones, no te creas que está calculando la rotación. Si puedes no te compliques y usa su misma idea. Además, una vez rotado el cubo este vuelve a su estado original por decirlo de alguna forma: el cubo no está rotado, es el mismo cubo pero en otra posición. La animación es la que te hace pensar que rota.

Ahora al meollo de la cuestión:

En la imagen los puntos que señalas no son ejes de rotación. Un eje de rotación es una linea, no un punto, y no se puede dar en 2D. Si entiendo bien a lo que te refieres, quieres que la imagen rote alrededor de ese punto (x,y), ¿es así? En ese caso estamos hablando de puntos de rotación (no es que eje de rotación esté MUY mal dicho, pero si se aclaran las cosas nos entendemos mejor xD)

Entonces para hacer una rotacion del cubo de 360 grados con el efecto que tiene bloxorz sería con esta secuencia:
No entiendo qué estás haciendo aquí. Nada. Y el dibujo me confunde aún más xD

Los objetos no rotan cambiando el (x,y) tranquilamente, debes aplicar transformaciones afines (y al ser rotación te aparecen senos y demás.)

De verdad que no entiendo nada de qué pretendes hacer aquí.

Entonces reorganizar los ejes de rotacion es un cacao que no se como resolver sin hacer infinitas comparaciones.
De nuevo no entiendo muy bien. ¿Qué ejes de rotación tienes que reorganizar? Tu cubo tiene una rotación y traslación, fin. No hay que reorganizar nada dado que la posición y rotación es sólo un vector: en 2D tienes (x,y,alpha) y en 3D (x,y,z,yaw,pitch,roll).

Tampoco entiendo a qué te refieres con las infinitas comparaciones. No hay ni un sólo if en una rotación, son todo operaciones matemáticas.

PD: si de verdad necesitas rotación en 3D lo que buscas son quaternions.

1 respuesta
storm2211

Si he entendido bien (que lo dudo), lo que yo haria si no te quieres meter con quaterniones es multiplicar las matrices de rotacion yaw, pitch, roll y la matriz de posicion. Y te dara la posicion deseada.

1 respuesta
elkaoD

#5 eso tiene demasiado problemas, desde gimbal lock hasta puntos límite (los dos "cénit".)

EnZo

#4 Sip, sé como lo hace Bloxorz. Y no puedo emularlo, ya que estoy usando Three.js.

Yo lo interpreto como el eje de rotacion Z. Que como bien dices es una linea que determina hacia donde debe girar el objeto. Pero en 2D es dificil representar esa linea con profundidad, así que hago un punto.

Los objetos no rotan cambiando el (x,y) tranquilamente, debes aplicar transformaciones afines (y al ser rotación te aparecen senos y demás.)
Es cierto. Pero la manera en que rotan si dependen de su eje de rotacion.

Entiendo lo que dices con que aplicando una rotacion y una traslacion adecuada debo conseguir el efecto deseado. Pero te equivocas. Para conseguir el efecto de Bloxorz hay que modificar el eje de rotacion. He hecho la animacion flash para que lo entiendas.
http://www.josema.es/temp/rotacion.html

En el primero el eje (o el punto como quieras llamarlo xD) de rotacion está en el centro que es su eje de rotacion original al crear cualquier objeto. Le he aplicado traslacion tal y como propones ademas de 90º de rotacion. Y el resultado es el que ves.
Sin embargo cambiando el eje a la esquina de abajo, el efecto que se consigue en el caso dos es el correcto. Y he tenido que aplicar traslacion alguna.

Entendiendo esto quizá ahora se entienda mejor lo explicado en #3

Y en el de abajo

1 respuesta
elkaoD

#7 no, con traslación y rotación lo puedes conseguir perfectamente. Imagina que estás rotando alrededor del eje Z (es decir, verías el cubo desplazarse a la derecha y rotar en la dirección de las agujas del reloj.)

PAINT SKILLS AHEAD (estoy escribiendo rápido desde casa de un colega, puede haber errores.)

Marrón = posición original del cubo
Rojo = cubo rotando

Marcados el desplazamiento en eje X, Y y rotación alpha.

Alpha lo conoces (es tu rotación actual, el parámetro). "Y" se puede calcular con la altura del triángulo negro y la altura original, "X" con el triángulo verde. En realidad hay varios triángulos en la figura que te permiten sacar los desplazamientos con trigonometría.

Aún así, si pones (0,0) en el punto donde quieres rotar y rotas, consigues lo que quieres.

Es tan fácil como trasladar a ese punto y rotar. Como sólo vas a rotar en un eje, no vas a tener problemas. Cuando el cubo esté "plano" reseteas la orientación y fin, te quitas de líos de suma de rotaciones que SIEMPRE acaban dando problemas (inherentemente la aritmética es imprecisa.) Este tipo de rotaciones precisas (cosas que no son estilo rotación de un coche, más "analógicas" ) se hacen con rotaciones falsas SIEMPRE... o al menos asegúrate de redondear a 90º en cada rotación, y resetear a 0º en los 360º!

2 respuestas
EnZo

#8 Puff, hacerlo con calculos trigonometricos iba a ser mas cacao todavia para mi.

Aún así, si pones (0,0) en el punto donde quieres rotar y rotas, consigues lo que quieres.
Creo que eso es lo que he intentado transmitir desde el principio. Al fin y al cabo para cambiar el eje de rotacion tengo que trasladarlo a su posicion correcta con un subgrupo.

Una vez entendido que tengo que cambiar el eje de rotacion. Entiendes mi problema a la hora de hacer varias rotaciones y tener que recolocar el eje de rotacion en funcion de a donde tengo que rotar?
http://postimage.org/image/d3exaywdj/

Muchas gracias por las parrafadas y por leerme. Es un tema pesao, pero llevo toda la semana con esto y no consigo hacerlo bien :(

1 respuesta
Igneus

no rota, pivota sobre uno de los ejes que permanece fijo y el resto de las esquinas tienen una rotacion entorno a ese eje. Los ejes que influyen en la rotación son los de la base que tendras que recalcular despues de cada rotacion.

1 respuesta
elkaoD

#9 entonces quédate con el último párrafo de #8.

#10 en geometría eso es rotar por el eje que define el lado de la caja, no pivotar.

1 respuesta
EnZo

#11 Si, pero lo de resetear la orientacion no es una solucion. Three.js no trae esa opcion que yo sepa. Y sigo teniendo el problema de tener que reorganizar el eje de rotacion/pivotacion en cada giro.

En cualquier caso gracias a todos. Ya veré si desisto o no... xD

2 respuestas
Byr0n

#12 Sin usar matemáticas y las herramientas que utilizas para trabajar te lo permiten, lo que haría seria crear un objeto padre en la posición de la esquina del rectángulo que pretendes rotar y anidarlo con el rectángulo, luego aplicamos la rotación en el eje Z al objeto padre y el rectángulo rotara como pretendes.

Si no te permite crear jerarquia de objetos con sus posiciones locales y absolutas y no tienes tampoco ninguna función que haga dicho comportamiento, tendrás que hacer mediante matrices una traslación y rotación, ademas de aplicarle un Lerp para que haga ese movimiento a lo largo del tiempo.

1 respuesta
EnZo

#13 Sip, como dije antes lo que hago es crear un "Objeto vacio" y en el meto mi cubo. Y moviendolo desde dentro consigo hacer el eje de rotacion que ya he comentado. Eso lo tengo hecho desde el principio. El problema lo tengo en reorganizar los ejes de rotacion tras varias rotaciones.

Imaginemos que mi cubo mide 100ancho 50alto (De momento solo en 2D) para recolocar el eje de rotacion hay que desplazar el cubo interno x=-50 y luego el objeto vacio que contiene el grupo sumarle x=+50. Igual con Y solo que en vez de 50 sería 25. Y quedaría algo así:
http://postimage.org/image/whtfyuj69/

Donde lo azul seria mi cubo visual. Y lo verde seria el objeto/grupo vacio en donde he metido mi cubo. Haciendo eso tengo mi cubo bien colocado, y al rotar el objeto/grupo hará lo que he comentado al principio.

MI PROBLEMA es que al hacer multiples giros recolocar el eje de rotacion es muy complejo para mí.

1 respuesta
Byr0n

#14 si el movimiento es siempre de dicha forma y hacia la derecha, al tener solo dos estados se forma un ciclo que puedes acotar de la siguiente manera:
Tras completar la primera rotación de 90º que se aprecia en esta imagen, http://postimage.org/image/d3exaywdj/ , una vez detectas que se ha completado lo que haces ahora es mover el padre "la parte larga" del rectángulo en la X hacia la derecha, luego al hijo le restas la misma cifra en la X y haces otra rotación de 90º y hará lo de la segunda linea.
En la ultima linea haces el mismo proceso pero utilizando "la parte corta" del rectángulo para aumentarle la X al padre, y disminuirla al Hijo.
Con esto tenemos ya el ciclo que se repetiría tantas veces quieras rotar 90º, habrá que tener en cuenta el estado inicial del rectángulo.

Hacia a la izquierda en el mismo eje seria el mismo proceso pero invirtiendo la operación de suma/resta.

elkaoD

#12 cómo no vas a poder poner la orientación que te de la gana a un objeto?

mesh.rotation.<component> = 0.0
1 respuesta
EnZo

#16 Modificarla/ponerla si que puedes pero resetearla a 0 despues de hacer un giro y que el objeto se quede con el giro hecho no. Es lo que entendí en #8.

#18 no entiendo

1 respuesta
elkaoD

#17 si puedes posicionar un cubo en un lugar del mapa y con una rotación específica inicialmente lo puedes hacer también tras cada movimiento.

#17 es geometría, no la vida real. Puedes hacer lo que te de la gana xD

2 respuestas
EnZo

#18 Si... Pero no puedes resetear la orientacion como si estuviese a 0 y mantener el giro. A menos que crees un padre y lo metas dentro. Tu cubo tendrá la orientacion del giro que le has aplicado previamente.

PD: Probablemente no estemos hablando de lo mismo xD

1 respuesta
elkaoD

#19 creo que tardamos menos si quedamos por alguna pizarra electrónica con chat de voz y lo hablamos xD

Usuarios habituales

  • elkaoD
  • EnZo
  • Byr0n
  • Igneus
  • storm2211