Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: Ynfiniti en Noviembre 03, 2015, 01:08:35 PM

Título: ¿Comprobar un punto (x,y) en un área rectangular rotada? [RESUELTO]
Publicado por: Ynfiniti en Noviembre 03, 2015, 01:08:35 PM
Quiero hacer un "point_in_rectangle_rotate", en donde se compruebe una coordenada determinada dentro de un rectángulo girado en un ángulo definido, ¿existe algún script para hacerlo, o alguien sabría como hacerlo?  :-[
Título: Re:¿Script para comprobar un punto (x,y) en un rectángulo rotado?
Publicado por: kostra en Noviembre 03, 2015, 01:24:17 PM
una representación gráfica estaría bien, almenos yo, no me he enterado de nada xD
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: Clamud en Noviembre 03, 2015, 03:29:22 PM
Podrías construir el rectángulo con dos triángulos y usar la función point_in_triangle:
http://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/point_in_triangle.html (http://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/point_in_triangle.html)

También podrías usar este script:
http://www.gmlscripts.com/script/point_in_polygon (http://www.gmlscripts.com/script/point_in_polygon)

Para calcular las posiciones de los vértices se tienen que usar las funciones lengthdir_*
Deberías dar información más detallada sobre cómo se va a usar el script, seguro se puede escribir uno más eficiente.
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: kostra en Noviembre 03, 2015, 06:37:50 PM
clamud, podrías porfavor explicarme de qué habláis? me picó la curiosidad xD
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: penumbra en Noviembre 03, 2015, 07:00:24 PM
Otra manera de hacerlo, si acaso quisieras evitar el realizar cálculos es crear un objeto "genérico" para representar a cualquier rectángulo (obj_rectangle) y hacer un scrip del estilo

punto_en_rectangulo(x1, y1, x2, y2, px, py, angulo)

1. El script crearía una instancia del obj_rectángulo
2. El script definiría una surface de las medidas dadas por los primeros 4 argumentos
3. En la surface, se dibujaría un rectángulo sólido igual a la medida de la surface.
4. El script usaría la función sprite_add_from_surface() junto con la surface previa para crear un sprite y asignárselo (sprite_index) a la instancia del obj_rectángulo recién creada
5. El script rotaría la instancia rectangular mediante image_angle según el argumento final del script.
6. El script devolvería true o false dependiendo de si la función collision_point() detecta que hay colisión con el rectángulo, en el punto dado por px,y py.

Habiendo resuelto la colisión, se puede destruír el rectángulo creado (lo que se puede hacer dentro o fuera del script).
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: Clamud en Noviembre 03, 2015, 08:26:57 PM
Lo más sencillo sería agregar un sprite al árbol de recursos antes de compilar el juego. De todos modos hice dos scripts, uno para dibujar un rectángulo rotado y el otro para detectar si un punto está adentro:
[gml]
///draw_rectangle_rotated( cx,cy, w,h, ang );
//                         0  1   2 3  4
d3d_transform_set_rotation_z( argument4 );
d3d_transform_add_translation( argument0,argument1,0 );
draw_rectangle( -argument2/2, -argument3/2, argument2/2, argument3/2, false );
d3d_transform_set_identity();
[/gml]
[gml]
///point_in_rectangle_rotated( cx,cy, w,h, px,py, ang );
//                             0  1   2 3  4  5   6
/* PUNTO EN RECTANGULO ROTADO
cx, cy: centro del rectangulo
w, h: anchura y altura
px, py: punto de prueba
ang: angulo de rotacion
*/

var cx,cy, w,h, px,py, angulo, Ax,Ay, Bx,By;
cx  = argument0;
cy  = argument1;
w   = argument2;
h   = argument3;
px  = argument4;
py  = argument5;
ang = argument6;

//Vector A
Ax = px-cx;
Ay = py-cy;

//Rotar A alrededor del eje z
Bx = lengthdir_x(Ax,ang) + lengthdir_y(Ay,ang);
By = lengthdir_x(Ay,ang) - lengthdir_y(Ax,ang);

//Resultado
return abs(Bx) < w/2 and abs(By) < h/2;
[/gml]
Existen muchas formas de resolver el problema, pero esta es compatible con :GM8: y :GMS:

El script anterior se puede optimizar de esta forma:
[gml]
var Ax,Ay, Bx,By;

Ax = argument4 - argument0;
Ay = argument5 - argument1;

Bx = lengthdir_x(Ax,argument6) + lengthdir_y(Ay,argument6);
By = lengthdir_x(Ay,argument6) - lengthdir_y(Ax,argument6);

return abs(Bx) < argument2/2 and abs(By) < argument3/2;
[/gml]
Adjunto un ejemplo.
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: penumbra en Noviembre 03, 2015, 09:42:02 PM
Cita de: Clamud en Noviembre 03, 2015, 08:26:57 PM
Existen muchas formas de resolver el problema
Aquí se discuten unas cuantas, si es que alguien se siente curioso por experimentar:
http://math.stackexchange.com/questions/190111/how-to-check-if-a-point-is-inside-a-rectangle
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: Guacusio en Noviembre 04, 2015, 01:01:54 AM
De todas las formas que han presentado hasta ahora, yo usaría la que me parece más sencilla que es la primera que propuso Clamud: hacer un par de llamadas a la función point_in_triangle
Título: Re:¿Script para comprobar un punto (x,y) en un área rectangulular rotada?
Publicado por: Ynfiniti en Noviembre 04, 2015, 01:08:46 AM
¡Muchas gracias a todos!  :D