Noviembre 03, 2015, 01:08:35 PM Ultima modificación: Noviembre 04, 2015, 01:09:29 AM por Ynfiniti
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?  :-[

una representación gráfica estaría bien, almenos yo, no me he enterado de nada xD
[spoiler="ola k ase clickarme o k ase"]la imagen no se quita xD
[/spoiler]

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

También podrías usar este script:
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.

clamud, podrías porfavor explicarme de qué habláis? me picó la curiosidad xD
[spoiler="ola k ase clickarme o k ase"]la imagen no se quita xD
[/spoiler]

#4 Noviembre 03, 2015, 07:00:24 PM Ultima modificación: Noviembre 03, 2015, 07:05:13 PM por penumbra
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).

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.


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