Find out whether a 2D line (y = a*x + b) intersects with a square without using "solve" (I need something faster)
6 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Perico Nasdemico
el 25 de Jul. de 2022
Comentada: Matt J
el 26 de Jul. de 2022
I want to find whether a line (defined by an equation of the type y = a*x + b) intersects with a square defined by 4 vertices (x_min, x_max, y_min, y_max). This needs to be evaluated thousands of times for many lines and squares using while loops, so I need something faster than my implementation using solve.
My code right now:
% example line parameters:
a = 1.61;
b = -3.1;
% example square parameters:
x_min = 7.5;
x_max = 8.5;
y_min = 9.5;
y_max = 10.5;
%% Finding wheter the line interects with the square (excerpt from a while loop)
do_they_intersect = false;
syms x y
tic;
solution = solve([y == a*x + b, x>x_min, x<x_max, y>y_min, y<y_max],[x,y]);
if rank(solution.x) > 0
do_they_intersect = true;
end
toc
Whether choosing < / > or <= / >= is not important.
I've seen I could define the square as a polygon and then use something like inpolygon(), but it seems it only works with numeric points, bot with symbolic values.
Any ideas?
Thanks
0 comentarios
Respuesta aceptada
Matt J
el 25 de Jul. de 2022
Editada: Matt J
el 25 de Jul. de 2022
Sort of like William's, but faster for some reason:
% example line parameters:
a = 1.61;
b = -3.1;
% example square parameters:
x_min = 7.5; x_max = 8.5;
y_min = 9.5; y_max = 10.5;
tic
q=[-a 1]';
V=[x_min y_min; ...
x_min y_max; ...
x_max y_min; ...
x_max y_max];
tmp=V*q;
do_they_intersect = any(tmp>b,1)&any(tmp<b) ;
toc
do_they_intersect
2 comentarios
Matt J
el 26 de Jul. de 2022
You're welcome, but curiious that you Accepted this answer. Bruno's is shorter and faster.
Más respuestas (3)
Bruno Luong
el 25 de Jul. de 2022
Editada: Bruno Luong
el 25 de Jul. de 2022
This shoudl do:
% example line parameters:
a = 1.61;
b = -3.1;
% example square parameters:
x_min = 7.5; x_max = 8.5;
y_min = 9.5; y_max = 10.5;
tic
y = a.*[x_min x_max] + b;
isintersected = any(y >= y_min) && any(y <= y_max);
toc
0 comentarios
Matt J
el 25 de Jul. de 2022
Editada: Matt J
el 25 de Jul. de 2022
Using linexlines2D,
is about 3 times faster. If the squares in question form a regular grid, though, there are ways to apply it much faster than that.
% example line parameters:
a = 1.61;
b = -3.1;
% example square parameters:
x_min = 7.5; x_max = 8.5;
y_min = 9.5; y_max = 10.5;
%% Finding wheter the line interects with the square (excerpt from a while loop)
do_they_intersect = false;
warning off
tic;
p=polyshape([x_min y_min; ...
x_min y_max; ...
x_max y_min; ...
x_max y_max]);
out=linexlines2D(p,[a,-1,b]);
do_they_intersect =any(~isnan(out),'all');
toc
0 comentarios
William Rose
el 25 de Jul. de 2022
If the slope, a, is positive, then, if there is an intersection, the line passes below or through the upper left corner, and the line passes above or through the lower right corner.
If the slope, a, is negative, then, if there is an intersection, the line passes above or thorugh the lower left corner, and the line passes below or through the upper right corner.
% example line parameters:
a = 1.61;
b = -3.1;
% example square parameters:
x_min = 7.5; x_max = 8.5;
y_min = 9.5; y_max = 10.5;
%% Finding wheter the line interects with the square (excerpt from a while loop)
tic;
if a>0
if a*x_min+b<=y_max && a*x_max+b>=y_min
fprintf('Intersects\n');
else
frpintf('Does not intersect\n');
end
else
if a*x_min+b>=y_min && a*x_max+b>=y_max
fprintf('Intersects\n');
else
frpintf('Does not intersect\n');
end
end
toc
This is a lot faster.
Good luck.
Ver también
Categorías
Más información sobre Mathematics and Optimization en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!