Autor: NiuWeb
Versión de GM utilizada: Studio 1.4.1657
Descripción: Conjunto de scripts que permiten generar un punto aleatorio dentro de los bordes de un rectángulo, círculo o vector (línea).
Código:

Función point_of_rectangle(x1, y1, x2, y2):
[gml]
///point_of_rectangle(x1, y1, x2, y2);
var x1, y1, x2, y2;
x1 = min(argument0, argument2);
y1 = min(argument1, argument3);
x2 = max(argument0, argument2);
y2 = max(argument1, argument3);

var n, s, t, w, h;
n = irandom(1);
s = irandom(1);
t = irandom(1);
w = x2 - x1;
h = y2 - y1;

var pos;
pos [ 0 ] = x1 + w*n + irandom(w)*(n xor 1)*s;
pos [ 1 ] = y1 + h*(!n and s)*t + irandom(h)*(n or !s);
return pos;
[/gml]
Este script genera un punto aleatorio dentro del borde de un rectángulo dado
Argumentos:
    x1: El componente horizontal del primer punto del rectángulo
    y1: El componente vertical del primer punto del rectángulo
    x2: El componente horizontal del segundo punto del rectángulo
    y2: El componente vertical del segundo punto del rectángulo
Devuelve: Un array con dos índices; el primero contiene la posición horizontal generada, y el segundo, la posición vertical generada.
Por ejemplo:
[gml]
var pos = point_of_rectangle(0, 0, room_width, room_height);
instance_create( pos [ 0 ], pos [ 1 ], automovil);
[/gml]
Se creará una instancia del objeto automovil en cualquier punto del borde de la sala


Función point_of_circle(x, y, r):
[gml]
///point_of_circle(x, y, r);
var xx, yy, r;
xx = argument0;
yy = argument1;
r = argument2;
var dir;
dir = irandom(360);
var lenx, leny;
lenx = lengthdir_x(r, dir);
leny = lengthdir_y(r, dir);

var pos;
pos [ 0 ] = xx + lenx;
pos [ 1 ] = yy + leny;
return pos;
[/gml]
Este script genera un punto aleatorio dentro del borde de un círculo dado
Argumentos:
    x: La posición horizontal del círculo
    y: La posición vertical del círculo
    r: El radio del círculo
Devuelve: Un array; su primer índice es la posición horizontal generada, y el segundo es la posición vertical generada.
Por ejemplo:
[gml]
var pos = point_of_circle(165, 165, 133);
instance_create(pos[0], pos[1], granada);
[/gml]
Se creará una instancia del objeto granada en un punto aleatorio dentro del borde de un círculo de 133 de radio ubicado en la posición [165,165]


Función point_of_line(x1, y1, x2, y2):
[gml]
///point_of_line(x1, y1, x2, y2);
var x1, y1, x2, y2;
x1 = argument0;
y1 = argument1;
x2 = argument2;
y2 = argument3;

var len, dir;
len = point_distance(x1, y1, x2, y2);
dir = point_direction(x1, y1, x2, y2);
var sel, lenx, leny;
sel = irandom(len);
lenx = lengthdir_x(sel, dir);
leny = lengthdir_y(sel, dir);

var pos;
pos [ 0 ] = x1 + lenx;
pos [ 1 ] = y1 + leny;
return pos;
[/gml]
Este script genera una posición aleatoria dentro de un vector o línea dada
Argumentos:
    x1: El componente horizontal del primer punto del vector
    y1: El componente vertical del primer punto del vector
    x2: El componente horizontal del segundo punto del vector
    y2: El componente vertical del segundo punto del vector
Devuelve: Un array; su primer índice es la posición horizontal generada, y el segundo es la posición vertical generada.
Por ejemplo:
[gml]
var pos = point_of_line(0, 0, room_width, room_height);
instance_create(pos[0], pos[1], efecto);
[/gml]
Se creará una instancia del objeto efecto en una posición aleatoria dentro de una línea (diagonal) que cruza el origen y el final de la sala.
alaberga regué el café.

BA:STFW&RTFM

#1 Mayo 14, 2016, 05:51:08 AM Ultima modificación: Mayo 14, 2016, 06:30:31 PM por Black_Cat
en vez de sacar los mayores y lo menores, no es más sencillo aplicar el módulo(o absoluto) de x1 y x2, lo mismo para y1, y2? 

lo que quiero decir es:

w = abs(x1 - x2)
h = abs(y1 - y2)


Estuve probando el script y lo que hace es devolver un punto de los bordes derecho e inferior.
A lo mejor el script no deberia tomar los 4 bordes del rectangulo?


dejo la version que estuve desarrollando para que devuelva un punto del borde, respeté la notación del anterior para mejor entendimiento:


[GML]

var x1,x2, y1, y2, w, h, c, p;


c = 0;
p[0] = 0;
p[1] = 0;


x1 = argument[0];
y1 = argument[1];
x2 = argument[2];
y2 = argument[3];


w = abs(x1 - x2);
h = abs(y1 - y2);


c = irandom(3);


switch(c){


    case 0:
        p[0] = x1 + irandom(w);
        p[1] = y1;   
    break;
   
    case 1:
        p[0] = x1 + irandom(w);
        p[1] = y2;
    break;
   
    case 2:
        p[0] = x1;
        p[1] = y1+ irandom(h);
    break;
   
    case 3:
        p[0] = x2;
        p[1] = y1 + irandom(h);
    break;
   
}


return p;
[/GML]



Sobre lo primero que dices, sobre usar min() y max(). La razón por la que los uso es porque, primero que todo, necesito hallar el valor de el menor de esos (obviamente), revisa las partes finales del script.
Ahora, gracias por el reporte :D , arreglarlo fue más complicado de lo que pensé xD, pero ya he modificado el script y ahora funciona como debería :D xD

Por cierto, creo que si hablamos de optimización, mis mínimos y máximos son son más eficientes que el switch de tu versión xDD (Además de que mi intención al hacerlo fue practicar lógica con los booleanos, razón principal por la que no usé un switch desde el comienzo)

NUEVO:
He agregado dos scripts más al grupo, que están relacionados con el original.
alaberga regué el café.

BA:STFW&RTFM