平面内任意生成俩线段L1 ,L2 编程判断两条线段是否相交,若相交,求出交点。
用转换坐标系的思路,Rotation Matrix:
- 将一根线段,变成新的坐标系的X轴。
- 判断第二根线段是否穿过新X轴(第一条线段所在直线)。
- 没有穿过说明俩线段没有交点。
- 如果穿过,再判断重合点位置分析是否俩线段有交点并求交点坐标。
- 最后将交点坐标转换为到主坐标系。
使用公式(公式适用3维,这里只用到2维平面 [3*1]=[3*3]*[3*1])
可以实现,新 老 坐标转换
MATLAB CODE:
clear;clc;
% 思路:将一根线段,变成新的坐标系的X轴,判断第二根线段是否与X轴有重合。
% 再判断重合点位置分析是否有交点或求交点坐标
x1 = [1,10]; y1 = [1,15]; % 线段一 任意设置
x2 = [-5,23]; y2 = [3,6]; % 线段二 任意设置
plot(x1,y1,'-*b',x2,y2,'-or'); %'-*b'——>线性,颜色,标记
hold on
alpha = atand(abs(y1(1)-y1(2))/abs(x1(1)-x1(2))); % 线段一与x轴夹角 度
% 根据不同情况转换坐标系生成 vec(3*3)新坐标系原点为线段1其中一个端点
%
% Rotation Matrix (2D): [x,y,1]' = vec * [x_new,y_new,1]'
%
% vec = [dot(X1,X), dot(Y1,X), x; X1(线段1),Y1为新坐标系坐标向量
% dot(X1,Y), dot(Y1,Y), y; X,Y 为原始坐标系坐标向量
% 0 , 0 , 1] x,y 为线段1其中一个端点坐标
%
% 自定义选择原则:线段1端点x坐标小的为新坐标原点
if x1(1)<x1(2)
if y1(1)<y1(2)
vec = [cosd(alpha),-sind(alpha),x1(1);
sind(alpha),cosd(alpha),y1(1);
0,0,1];
else
vec = [cosd(alpha),sind(alpha),x1(1);
-sind(alpha),cosd(alpha),y1(1);
0,0,1];
end
elseif x1(1)>x1(2)
if y1(2)<y1(1)
vec = [cosd(alpha),-sind(alpha),x2(1);
sind(alpha),cosd(alpha),y2(1);
0,0,1];
else
vec = [cosd(alpha),sind(alpha),x2(1);
-sind(alpha),cosd(alpha),y2(1);
0,0,1];
end
else
sprintf("points coincide");
end
% Rotation Matrix (2D): [x,y,1]' = vec * [x_new,y_new,1]'
% 生成第二个线段在新坐标的位置
p1 = inv(vec)*[x2(1);y2(1);1]; % 新坐标[x_new,y_new,1]'
p2 = inv(vec)*[x2(2);y2(2);1];
% 判断交点
if p1(2)*p2(2)>0 % 俩点同向无交点
sprintf("no intersection point")
else % 求线段2所在直线与新x轴交点
k=((p1(2)-p2(2))/(p1(1)-p2(1)));
b=p1(2)-k*p1(1);
iPoint=-b/k; % 新x轴交点坐标
if iPoint<0 % 判断交点是否在线段1上
sprintf("no intersection point")
else
if iPoint > sqrt((y1(1)-y1(2))^2+(x1(1)-x1(2))^2)
sprintf("no intersection point")
else % 如果在,求其点并转换为老坐标系坐标
oldPoint = vec*[iPoint;0;1];
plot(oldPoint(1),oldPoint(2),'*y')
sprintf("intersection point: %i, %i",oldPoint(1),oldPoint(2))
end
end
end