# GMLscripts.com

Discuss and collaborate on GML scripts

You are not logged in.

## #1 2021-07-13 15:30:03

maras
Member
Registered: 2021-04-25
Posts: 28
Website

### Line x shape collisions

Some line x shape intersections converted to GM

Line and circle

Expand/// line_circle_intersection(x1, y1, x2, y2, cx, cy, rad)
//
// returns bool
//
//	x1	line x from, real
//	y1	line y from, real
//	x2	line x to, real
//	y2	line y to, real
//	cx	circle x, real
//	cy	circle y, real
//

function line_circle_intersection(x1, y1, x2, y2, cx, cy, rad) {

var ac1 = cx - x1;
var ac2 = cy - y1;
var ab1 = x2 - x1;
var ab2 = y2 - y1;

var abab = dot_product(ab1, ab2, ab1, ab2);
var acab = dot_product(ac1, ac2, ab1, ab2);
var t = clamp(acab/abab, 0, 1);

var h1 = ab1 * t + x1 - cx;
var h2 = ab2 * t + y1 - cy;

}

Line and rectangle

Expand/// line_rect_intersection(x1, y1, x2, y2, rx1, ry1, rx2, ry2)
//
// returns bool
//
//	x1	line x from, real
//	y1	line y from, real
//	x2	line x to, real
//	y2	line y to, real
//	rx1	rectangle min x, real
//	ry1	rectangle min y, real
//	rx2	rectangle max x, real
//	ry2	rectangle max y, real
//

function line_rect_intersection(x1, y1, x2, y2, rx1, ry1, rx2, ry2) {

if point_in_rectangle(x1, y1, rx1+1, ry1+1, rx2-1, ry2-1) return true;
if point_in_rectangle(x2, y2, rx1+1, ry1+1, rx2-1, ry2-1) return true;

if ((x1 <= rx1 and x2 <= rx1)
or (y1 <= ry1 and y2 <= ry1)
or (x1 >= rx2 and x2 >= rx2)
or (y1 >= ry2 and y2 >= ry2))
return false;

var m = (y2 - y1) / (x2 - x1);

var yy = m * (rx1 - x1) + y1;
if (yy > ry1 and yy < ry2) return true;

yy = m * (rx2 - x1) + y1;
if (yy > ry1 and yy < ry2) return true;

var xx = (ry1 - y1) / m + x1;
if (xx > rx1 and xx < rx2) return true;

xx = (ry2 - y1) / m + x1;
if (xx > rx1 and xx < rx2) return true;

return false;
}

Line and rotated rectangle (rotates around the middle)

Expand/// line_rot_rect_intersection(x1, y1, x2, y2, rx1, ry1, rx2, ry2, rot)
//
// returns bool
//
//	x1	line x from, real
//	y1	line y from, real
//	x2	line x to, real
//	y2	line y to, real
//	rx1	rectangle min x, real
//	ry1	rectangle min y, real
//	rx2	rectangle max x, real
//	ry2	rectangle max y, real
//	rot	rectangle rotation, real
//

function line_rot_rect_intersection(x1, y1, x2, y2, rx1, ry1, rx2, ry2, rot) {

var pivot_x = (rx1 + rx2) * 0.5;
var pivot_y = (ry1 + ry2) * 0.5;

var s = [
[point_distance(pivot_x, pivot_y, x1, y1), point_direction(pivot_x, pivot_y, x1, y1) - rot],
[point_distance(pivot_x, pivot_y, x2, y2), point_direction(pivot_x, pivot_y, x2, y2) - rot]
];

x1 = pivot_x + lengthdir_x(s[0][0], s[0][1]);
y1 = pivot_y + lengthdir_y(s[0][0], s[0][1]);
x2 = pivot_x + lengthdir_x(s[1][0], s[1][1]);
y2 = pivot_y + lengthdir_y(s[1][0], s[1][1]);

if point_in_rectangle(x1, y1, rx1+1, ry1+1, rx2-1, ry2-1) return true;
if point_in_rectangle(x2, y2, rx1+1, ry1+1, rx2-1, ry2-1) return true;

if ((x1 <= rx1 and x2 <= rx1)
or (y1 <= ry1 and y2 <= ry1)
or (x1 >= rx2 and x2 >= rx2)
or (y1 >= ry2 and y2 >= ry2))
return false;

var m = (y2 - y1) / (x2 - x1);

var yy = m * (rx1 - x1) + y1;
if (yy > ry1 and yy < ry2) return true;

yy = m * (rx2 - x1) + y1;
if (yy > ry1 and yy < ry2) return true;

var xx = (ry1 - y1) / m + x1;
if (xx > rx1 and xx < rx2) return true;

xx = (ry2 - y1) / m + x1;
if (xx > rx1 and xx < rx2) return true;

return false;
}

Line and line

Expand/// line_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4)
//
// returns bool
//
//	x1	line 1 x from, real
//	y1	line 1 y from, real
//	x2	line 1 x to, real
//	y2	line 1 y to, real
//	x3	line 2 x from, real
//	y3	line 2 y from, real
//	x4	line 2 x to, real
//	y4	line 2 y to, real
//

function line_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4) {

var s1_x = x2 - x1;
var s1_y = y2 - y1;
var s2_x = x4 - x3;
var s2_y = y4 - y3;

var s = (-s1_y * (x1 - x3) + s1_x * (y1 - y3)) / (-s2_x * s1_y + s1_x * s2_y);
var t = ( s2_x * (y1 - y3) - s2_y * (x1 - x3)) / (-s2_x * s1_y + s1_x * s2_y);

return s >= 0 and s <= 1 and t >= 0 and t <= 1;
}

Last edited by maras (2021-07-16 08:25:15)

I'm on the official GM discord > maras_cz

Offline