Diciembre 29, 2012, 07:04:56 AM Ultima modificación: Diciembre 31, 2012, 05:22:29 AM por romon_28
Nombre del creador: romon_28.
Breve descripción de su función: Devueve un valor x a un valor entre 0 y 360
Versión GM utilizada:   :GM5: :GM6: :GM7: :GM8: :GMS: :GMHTML5: :GMMAC:
Código del Script "Angular( x )":
/*
Angular( x );
x: Direccion.

----------------------------------------------------------------
Explicasión practica:
direction = 270+180; // Osea: direction=450
direction = Angular( (270+180) ); // direction=90
----------------------------------------------------------------
Creado por: RoMoN.
*/

if argument0>360
|| argument0<0
{
return (((argument0/360)-floor(argument0/360))*360);
}

return (argument0);

No es más facil así?
[gml]while argument0>360 {argument0-=360}
while argument0<0 {argument0+=360}[/gml]
Digo por la optimización, no es lo mismo sumar que dividir, hacer floor y multiplicar




Yo diria que lo más facil rápido es usar mod, ademas de ser mas entendible.
[gml]argument0= argument0 mod 360[/gml]

Aunque eso te deja tu numero con un rango entre 360 y -360 y de hecho muchas veces es lo que quieres, aunque si quieres tu numero entre 0 y 360 positivo pudes añadir esto:
[gml]argument0= argument0 mod 360;
if argument0>=0 return ( argument0 );
return( 360+argument0 );[/gml]

Cita de: Texic en Diciembre 29, 2012, 08:29:06 PM
No es más facil así?
[gml]while argument0>360 {argument0-=360}
while argument0<0 {argument0+=360}[/gml]
Digo por la optimización, no es lo mismo sumar que dividir, hacer floor y multiplicar
Un pequeño problema; el primer while debería decir >=360, sino, el script podría devolver 360 (cuando debería devolver 0). La versión de romon_28 también devuelve 360 a veces.

Creo que la mejor forma si el número es positivo es usando mod, como propuso brunoxzx. Pero no recuerdo bien como es que el mod de GM maneja los mumeros negativos...
La forma que se me ocurre ahora de hacerlo es:
[gml]return (abs(argument0) mod 360) * sign(argument0) + 360 * ((abs(argument0) mod 360) * sign(argument0) < 0);[/gml]
Me gusta porque es una sola línea, pero no sé si es más rápida que las demás xD.
Si la versión de brunoxzx funciona bien con números menores a -360, creo que sería la mejor.
Si alguien que tenga GM se anima a hacer una prueba de velocidad...
Hice la prueba en Python, y estos son los tiempos de ejecución mas bajos para cada script, en el orden en el que fueron posteados:
Citar0.000007
0.000006
0.000004
0.000012
Aparentemente el mío es el más lento, por lejos jaja. El de brunoxzx parece ser el más rápido. La única duda que me queda es si maneja bien los números negativos.
Vim.

Cita de: Wadk en Enero 06, 2013, 06:57:04 AM
Cita de: Texic en Diciembre 29, 2012, 08:29:06 PM
No es más facil así?
[gml]while argument0>360 {argument0-=360}
while argument0<0 {argument0+=360}[/gml]
Digo por la optimización, no es lo mismo sumar que dividir, hacer floor y multiplicar
Un pequeño problema; el primer while debería decir >=360, sino, el script podría devolver 360 (cuando debería devolver 0). La versión de romon_28 también devuelve 360 a veces.

Creo que la mejor forma si el número es positivo es usando mod, como propuso brunoxzx. Pero no recuerdo bien como es que el mod de GM maneja los mumeros negativos...
La forma que se me ocurre ahora de hacerlo es:
[gml]return (abs(argument0) mod 360) * sign(argument0) + 360 * ((abs(argument0) mod 360) * sign(argument0) < 0);[/gml]
Me gusta porque es una sola línea, pero no sé si es más rápida que las demás xD.
Si la versión de brunoxzx funciona bien con números menores a -360, creo que sería la mejor.
Si alguien que tenga GM se anima a hacer una prueba de velocidad...
Hice la prueba en Python, y estos son los tiempos de ejecución mas bajos para cada script, en el orden en el que fueron posteados:
Citar0.000007
0.000006
0.000004
0.000012
Aparentemente el mío es el más lento, por lejos jaja. El de brunoxzx parece ser el más rápido. La única duda que me queda es si maneja bien los números negativos.
no seria así?
return abs ( ((((argument0 - argument1) mod 360) + 540) mod 360) - 180 )
Padre Nuestro del Programador de C           
C Nuestro que estas en la Memoria,
Compilado sea tu código,
venga a nosotros tu software,
carguense tus punteros.
así en la RAM como en el Disco Duro,
Danos hoy nuestro Array de cada día,
Perdona nuestros Warnings,
así como nosotros también los eliminamos,
no nos dejes caer en Bucles,
y libranos del Windows, Enter.

Cita de: Mr.Dudas en Enero 07, 2013, 03:44:17 PMno seria así?
return abs ( ((((argument0 - argument1) mod 360) + 540) mod 360) - 180 )
No parece que haga lo mismo... para empezar lleva dos argumentos...
Si lo que quisiste decir fue esto:
[gml]return abs((argument0 mod 360 + 540) mod 360 - 180);[/gml]
en ese caso, pues tampoco.  El tiempo menor de ejecución de ese script me dio 0.000006, igual que el de Texic. Y no da el resultado correcto en unos cuantos casos, a veces ni siquiera un resultado equivalente.
Estas son algunas de las pruebas que hice. El valor de la izquierda es el argumento de la función, el del medio es lo que devuelve, y el de la derecha lo que debería devolver:
0 0 0
720 0 0
-362 2 358
-361 1 359
-360 0 0
-100 100 260
100 100 100
360 0 0
361 1 1
362 2 2
-720 0 0
Vim.

#6 Enero 08, 2013, 12:08:26 PM Ultima modificación: Enero 08, 2013, 12:19:08 PM por brunoxzx
Cita de: Wadk en Enero 06, 2013, 06:57:04 AM
Citar0.000007
0.000006
0.000004
0.000012
Aparentemente el mío es el más lento, por lejos jaja. El de brunoxzx parece ser el más rápido. La única duda que me queda es si maneja bien los números negativos.
El mod en números negativos hace lo mismo solo que devuelve el resultado en negativo. Por ejemplo -450 mod 360 debe dar -90.

Siempre me sucede que hago códigos de una sola linea para ahorrarme if's pero al final casi siempre resultan ser mas lentos xD y aveces menos legibles.

Porcieto mi script en una sola linea seria:
[gml]return( argument0 mod 360 + 360*(argument0<0) );[/gml]
y tal vez sea igual de rápido que el anterior.

Cita de: Wadk en Enero 08, 2013, 12:37:33 AM
Cita de: Mr.Dudas en Enero 07, 2013, 03:44:17 PMno seria así?
return abs ( ((((argument0 - argument1) mod 360) + 540) mod 360) - 180 )
No parece que haga lo mismo... para empezar lleva dos argumentos...
Si lo que quisiste decir fue esto:
[gml]return abs((argument0 mod 360 + 540) mod 360 - 180);[/gml]
Lo que hace el script te MR.Dudas es devolver la diferencia entre dos ángulos y esta diferencia es un numero entre -180 y 180 es muy útil, por ejemplo cuando quieres iterar entre 2 ángulos.

Por ejemplo si quieres que el angulo de un brazo que está a 72 grados gire para tomar algún objeto a 350 grados lo primero que se hace es obtener la diferencia entre los dos ángulos con el script anterior (debería dar -82 grados de diferencia) y entonces puedes hacer que el brazo se mueva los -82 grados en un tiempo determinado al gusto.

Edit: Releyendo el post me doy cuenta de que el script que MR.Dudas puso tiene un abs() al inicio, lo cual haría que el script devuelva el angulo entre 0 y 180, no le veo mucho sentido ya que no devolvería el signo de la diferencia. Eso me hace pensar que ni el mismo MR.Dudas sabia lo que el script hacia.

Cita de: brunoxzx en Enero 08, 2013, 12:08:26 PM
Cita de: Wadk en Enero 06, 2013, 06:57:04 AM
Citar0.000007
0.000006
0.000004
0.000012
Aparentemente el mío es el más lento, por lejos jaja. El de brunoxzx parece ser el más rápido. La única duda que me queda es si maneja bien los números negativos.
El mod en números negativos hace lo mismo solo que devuelve el resultado en negativo. Por ejemplo -450 mod 360 debe dar -90.
Entonces tu script es el mejor hasta ahora. Felicidades jaja.

Cita de: brunoxzx en Enero 08, 2013, 12:08:26 PM
Porcieto mi script en una sola linea seria:
[gml]return( argument0 mod 360 + 360*(argument0<0) );[/gml]
y tal vez sea igual de rápido que el anterior.
Se ve bien, aunque no puedo probar si funciona en Python porque el mod de Python (que se escribe %) se comporta distinto para números negativos...
De cualquier forma, la velocidad me dio exactamente igual que la versión con el if.
Vim.

Me parece que tu script hace lo mismo que el que puse hace varios años atrás: http://www.comunidadgm.org/desarrollo-de-scripts/regular-193ngulo/
Vota nuestro proyecto en Steam Greenlight:

Estudios Naicura Ltda