我正在寻找一种快速而优雅的方式来解决这个问题: 我有两条非连续线,就像这张图片中的黑线一样:
对于每一个,我有两个向量 - 一个定义每个段的起点,另一个定义终点。
我正在寻找一个MATLAB脚本,它将为blue行提供起点和终点,这是两条线的交叉点。
当然,我可以创建两个向量,每个向量包含黑色线条中的所有元素,然后使用“相交”。但是,由于这里的数字是数十亿,这些矢量的大小将是巨大的,交叉点将需要很长时间。
有什么想法吗?
答案 0 :(得分:3)
好问题!
这是一个无循环的解决方案,用于组合 n 不连续的行( n 在原始帖子中为2 )。
考虑 n 不连续线,每条线由其起点和终点定义。还要考虑任意测试点P.设S表示解,即,定义为所有输入线的交点的不连续线。关键的想法是: P在S中,当且仅当P左边的起点数减去P左边的停止点数等于n(考虑所有线的所有点)
这个想法可以通过矢量化操作紧凑地应用:
start = {[1 11 21], [2 10 15 24]}; %// start points
stop = {[3 14 25], [3 12 18 27]}; %// stop points
%// start and stop are cell arrays containing n vectors, with n arbitrary
n = numel(start);
start_cat = horzcat(start{:}); %// concat all start points
stop_cat = horzcat(stop{:}); %// concat all stop points
m = [ start_cat stop_cat; ones(1,numel(start_cat)) -ones(1,numel(stop_cat)) ].';
%'// column 1 contains all start and stop points.
%// column 2 indicates if each point is a start or a stop point
m = sortrows(m,1); %// sort all start and stop points (column 1),
%// keeping track of whether each point is a start or a stop point (column 2)
ind = find(cumsum(m(:,2))==n); %// test the indicated condition
result_start = m(ind,1).'; %'// start points of the solution
result_stop = m(ind+1,1).'; %'// stop points of the solution
根据以上数据,结果是
result_start =
2 11 24
result_stop =
3 12 25
答案 1 :(得分:0)
您对离散化的想法很好,但我没有使用固定步长,而是将其缩小到相关点。联合的起点或终点是其中一个输入的起点或终点。
%first input
v{1}=[1,3,5,7;2,4,6,8];
%second input
v{2}=[2.5,6.5;4,8];
%solution can only contain these values:
relevantPoints=union(v{1}(:),v{2}(:));
%logical matrix: row i column j is true if input i contains segment j
%numel(relevantPoints) Points = numel(relevantPoints)-1 Segments
bn=false(size(v,2),numel(relevantPoints)-1);
for vector=1:numel(v)
c=v{vector};
for segment=1:size(c,2)
thissegment=c(:,segment);
%set all segments of bn to true, which are covered by the input segment
bn(vector,find(relevantPoints==thissegment(1)):find(relevantPoints==thissegment(2))-1)=true;
end
end
%finally the logic we want to apply
resultingSegments=and(bn(1,:),bn(2,:));
seg=[relevantPoints(find(resultingSegments))';relevantPoints(find(resultingSegments)+1)'];