MATLAB Answers

0

How to trim segments to fit a square

Asked by Tchilabalo on 20 Aug 2019
Latest activity Edited by Matt J
on 21 Aug 2019
intermed=[X1 X2 Y1 Y2 m b]% where (X1,Y1) represents the lower left endpoint, (X2, Y2) represents the upper right endpoint, m and b are the slope and intercept
Tau = zeros(size(intermed));
for i=1:length(intermed)
if intermed(i,3)<0.00% Removes any Y1 less than 0
Tau(i,3)=0.00% Replace any Y1<0 by 0
Tau(i,1)=(0.00001-intermed(i,6))/(intermed(i,5));% Computes the new X1 using intercept and slope
else if intermed(i,4)>40.00% Removes any Y2 less than 0
Tau(i,4)=40% Replace any Y2>40 by 40
Tau(i,2)=(40-intermed(i,6))/(intermed(i,5));
else
Tau(i,1)=intermed(i,1);
Tau(i,2)=intermed(i,2);
Tau(i,3)=intermed(i,3);
Tau(i,4)=intermed(i,4);
Tau(i,5)=intermed(i,5);
Tau(i,6)=intermed(i,6);
end
end
end
I have 100 segments with the endpoints coordinates. I want to trim these segments to fit into a square of 40 by 40. X coordinates are already in the range 0-40. But for the Y coordinate i have some outliers (<0 and >40). The code above is my attempt to trim these outliers, but it doesn't work. Thanks in advance.

  0 Comments

Sign in to comment.

Tags

2 Answers

Answer by Matt J
on 20 Aug 2019
Edited by Matt J
on 21 Aug 2019
 Accepted Answer

One solution is to use intersectionHull() from here
Note: this will also work if X1,X2 violate the boundaries as well.
% Generate some test data
Window=40;
square=[0 0; 0 Window; Window 0; Window Window];
N=20;
X1=rand(N,1)*(Window+20)-10;
X2=rand(N,1)*(Window+20)-10;
Y1=rand(N,1)*(Window+20)-10;
Y2=rand(N,1)*(Window+20)-10;
intermed=[X1,X2,Y1,Y2]; %original
%Perform the truncations
Tau=intermed;
for i=1:N
v= reshape( intermed(i,:) , 2,[]);
S=intersectionHull('vert',square,'vert',v);
if isempty(S.vert)
Tau(i,:)=nan;
else
V=sortrows(S.vert);
Tau(i,:)=[V(1,1) V(end,1) V(1,2) V(end,2)]; %truncated
end
end
% Check the trim
close all
plot(intermed(:,[1 2])',intermed(:,[3 4])','bo-'); % original data
hold on
plot(Tau(:,[1 2])',Tau(:,[3 4])','r+-','linewidth',2); % trimmed data
plot([0 Window Window 0 0],[0 0 Window Window 0],'k-.'); % box

  4 Comments

Show 1 older comment
Matt J
on 21 Aug 2019
See my updated answer.
Hi Matt, It is working perfectly. Thanks!
Matt J
on 21 Aug 2019
You're welcome. But Bruno's solution will probably be faster if your X1,X2 are already within bounds.

Sign in to comment.


Answer by Bruno Luong
on 21 Aug 2019
Edited by Bruno Luong
on 21 Aug 2019

% Generate some test data, put 100 instead of 20 if you like
X1=rand(20,1)*40;
X2=rand(20,1)*40;
Y1=rand(20,1)*60-10;
Y2=rand(20,1)*60-10;
X = [X1, X2];
Y = [Y1, Y2];
intermed=[X, Y]; % add other columns if you like
Yt = max(min(Y,40),0);
dY = diff(Y,1,2);
dX = diff(X,1,2);
b = dY ~= 0;
Xt = X;
Xt(b,:) = X1(b) + (dX(b)./dY(b)) .* (Yt(b,:)-Y1(b));
Tau = [Xt, Yt]; % add other columns if you like
Tau(any(Xt<0 | Xt>40,2),1:4) = NaN;
% Check the trim
close all
plot(intermed(:,[1 2])',intermed(:,[3 4])','bo-'); % original data
hold on
plot(Tau(:,[1 2])',Tau(:,[3 4])','r+-','linewidth',2); % trimmed data
plot([0 40 40 0 0],[0 0 40 40 0],'k-.'); % box

  0 Comments

Sign in to comment.