Noticias

¡Ayuda a la Comunidad GM, haz una donación!

* Sponsor

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Autor Tema: point_distance y point_direction  (Leído 369 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado dixon

en: Abril 21, 2021, 04:24:40 am
Nombre del autor : Reyes Dávila.
Breve descripción de su función : Calcular la distancia  y la dirección entre dos puntos de igual forma que las funciones originales, sin usar las funciones originales.
Versión GM utilizada : Game maker 4.3c (March 4, 2003) hasta la Game Maker htm5.

Código del script:
point_direction_plus(x1,y1,x2,y2)
///point_direction_plus(x1,y1,x2,y2)
//Obteniendo argumentos iniciales
//X1 y Y1 representan el origen o el objeto origen del cual se quiere
//tomar la dirección.
x1=argument0;
y1=argument1;
x2=argument2;
y2=argument3;

//Determinando las medidas entre puntos (no es la distancia entre puntos)
//No es más que el valor absoluto de la resta de los valores en X y Y.
//en otras palabras estamos calculando las longitudes de los catetos de
//un triángulo rectángulo, para luego poder emplear el teorema de pitagoras.
medidaX=abs(x1-x2); //medida en X
medidaY=abs(y1-y2); //medida en Y

//Calculando la dirección:
//Verificando que la longitud o medida X nunca llegue a cero para evitar error en la división.
//Si la medida llegara a cero se produciría un error de división, es
//por eso que cuando la medida X llega a cero se tomará un valor muy
//cercano a cero, pero nunca cero.
if(medidaX=0){medidaX=0.0005}

//Calculando el arco tangente de la división de la medida Y
//entre la medida X, esto es solo la formula trigonométrica que se
//utiliza para determinar el ángulo de un triángulo rectángulo.
angulo1=arctan(medidaY/medidaX);

//Pasando radianes a ángulo
//Como el resultado anterior es devuelto en radianes se
//utiliza la siguiente función para pasarlo a grados.
//Hay muchas formas de pasar radianes a grados:
//Usando la función radtodeg de la siguiente forma:
//angulo1=radtodeg(angulo1);
//O tambien podemos multiplicar radianes por 57.296 (ya
//que un radian son 57.296 grados) de la siguiente manera:
//angulo1=angulo1*57.296
//Yo prefiero la que no usa funciones del game maker.
angulo1=angulo1*57.296;

//Determinando el cuadrante del plano en donde se encuentra el punto (x2,y2).
//La fórmula anterior funciona correctamente solo para el cuadrante I del plano,
//es por eso que deben crearse condiciones para poder ajustar los valores
//según el cuadrante en donde se encuentre el punto.
cuadrante="";
if(x1 <= x2 && y1 >= y2){cuadrante="I"}
if(x1 >= x2 && y1 >= y2){cuadrante="II"}
if(x1 >= x2 && y1 <= y2){cuadrante="III"}
if(x1 <= x2 && y1 <= y2){cuadrante="IV"}

//Ajustando los valores según el cuadrante
//Según en donde se encuentre el punto en el plano, se sumarán o restarán
//los grados necesarios para poder obtener los grados correctos.

if(cuadrante="I"){angulo1=angulo1}
if(cuadrante="II"){angulo1=180-angulo1}
if(cuadrante="III"){angulo1=180+angulo1}
if(cuadrante="IV"){angulo1=360-angulo1}

//Devolviendo la dirección entre los puntos en grados.
return angulo1;


point_distance_plus(x1,y1,x2,y2)
///point_distance_plus(x1,y1,x2,y2)
//Obteniendo argumentos iniciales
//X1 y Y1 representan el origen o el objeto origen del cual se quiere
//tomar la distancia.
x1=argument0;
y1=argument1;
x2=argument2;
y2=argument3;

//Determinando las medidas entre puntos (no es la distancia entre puntos)
//No es más que el valor absoluto de la resta de los valores en X y Y.
//en otras palabras estamos calculando las longitudes de los catetos de
//un triángulo rectángulo.
medidaX=abs(x1-x2); //medida en X
medidaY=abs(y1-y2); //medida en Y

//Calculando la distancia
//El teorema de Pitágoras
//Si a y b son las longitudes de los catetos de un
//triángulo rectángulo y c es la longitud de la hipotenusa,
//entonces la suma de los cuadrados de las longitudes de los
//catetos es igual al cuadrado de la longitud de la hipotenusa.
distancia=power(medidaX,2)+power(medidaY,2)
distancia=sqrt(distancia);

//Devolviendo la distancia
return distancia;


Modo de uso: se emplean igual que las funciones originales “point_direction” y “point_distance”.
Fueron creadas para ser utilizadas si fallaren las funciones originales al exportar a alguna plataforma y también para que sirvan de guía a la hora de comprender cómo calculan la distancia y la dirección.

Imágenes que utilicé para entender el procedimiento



Bibliografías consultadas

Calcular ángulos
https://es.wikihow.com/calcular-%C3%A1ngulos

TRIANGULO ISÓSELES
https://es.wikipedia.org/wiki/Tri%C3%A1ngulo_is%C3%B3sceles

El teorema de Pitágoras
https://www.montereyinstitute.org/courses/DevelopmentalMath/TEXTGROUP-1-8_RESOURCE/U07_L1_T4_text_final_es.html
« Última modificación: Abril 21, 2021, 04:35:39 am por dixon »

Si Dios quiere; Limpiaré la oficina, puliré el piso y les serviré café a todos, luego, me enseñarán a programar e iré a comprarles más café.
 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado brunoxzx

Respuesta #1 en: Junio 05, 2021, 09:16:47 am
jojojo, un par de scripts solo para practicar, me da gusto que los compartas. Tengo un par de tips.

La primera cuestión, es que en ambos scripts estás usando el valor absoluto, en el caso de calcular la distancia no es necesario usarlo, puedes tratar quitandolo y no va a alterar tu código, eso es por que al elevar un número al cuadrado se vuelve positivo. Otra cosa es que en ese script usas la función power, me parece que game maker tiene una función sqr que eleva al cuadrado directamente, pero si no, no es necesario usarla puedes hacer la multiplicación allí de corrido, te digo por que seguro es un poquititín más optimo que usar la función de power que al ser más general, seguro come más.

En el script de calcular la dirección encuentro varios comentarios que podrían serte de utilidad. El primero sería que en el if de cuando la medidadX es 0, ya le pongas un return que mande 90 grados si es para arriba y -90 si es para abajo, creo que eso se vería más pro que el truquillo que usaste xp, igualmente está bien.

Otro de optimizan sería que no utilices strings para nombrar los cuadrantes, entiendo que lo haces por legibilidad pero cuando menos lo consideraría una mala practica y es poco menos eficiente el comparar cadenas que simplemente números, y también guardarlas. Lo mejor si quieres legibilidad seria hacer un enumerador, y poner para una entrada para cada cuadrante, si no pues usar números, al fin y acabo eso son. También me da algo de curiosidad que hayas decidido añadir lo del chequeo de cuadrantes en dos partes, cuando pudiste haberte evitado todo eso y directamente hacer las sumas de ángulos, literal esos 8 if se podrían transformar en 4 y sin hacer comparaciones innecesarias.

Por último y lo más importante creo, es que también con esto de usar los valores absolutos te pierdes de algo interesante en el script que devuelve el ángulo y es que la función del arcotangente también sirve para valores negativos!, concretamente cubre los cuadrantes 1 y 4, de modo que si quitas esos valores absolutos solo tendrías que hacer un if para revisar si está del lado derecho o del izquierdo (en los cuadrantes 2 y 3) y en tal caso sumarle los 180 grados.

mmm también existe una función llamada arctan2, que ya funciona para todos los cuadrantes, pero bueno esa ya sería como algo de trampa si lo que quieres hacer es entrarle a lo manual.

 
Los siguientes usuarios dieron las gracias a este tema: dixon