How can i extract specific points that meet a condition from given data?

Hello there,
I want to detect the points that belongs to the second circle in the plot.
These are my coordinates:
I tried this:
%% Our Problem
% We want to detect points belonging to the second circle in the middle.
% We look for points that have a distance less than 30 to the start-
% point and save them in a new Matrix called D
% Replace the start-point with a new one, the maximum of Matrix D.
% Find new points, go on til we dont find any new points nearby.
start(1,:) = circlestartingpoints(2,:)
D = circlestartingpoints(2,:);
distances = 1;
while min(distances) < 30
dx = X(:,1) - start(1,1); dy = X(:,2) - start(1,2);
distances = sqrt(dx.^2+dy.^2);
indx = find(distances > 0 & distances < 30);
D = [D;X(indx,:)];
start(1,:) = max(D);
X(indx,:) = [];
end
D = unique(D, 'rows')
It works somehow, but it doesnt save every point that belongs to the circle segment.
I attached the used matrix "xycoords.txt'
This is my code.
X = readmatrix('xycoords.txt');
%% 1) find approximatley intersection with y-axis
X0 = yintersectionappr(X(:,1), X(:,2), 10)
%% 2) Detect starting points of circles and how many circles we have
circlestartingpoints = detectstartingpoints(X0)
n = size(circlestartingpoints, 1)
%% 3) Plot data, plot circlestartingpoints in red colour.
scatter(x, y, 20, 'MarkerEdgeColor', [0 .5 .5], 'MarkerFaceColor', [0 .7 .7])
axis equal
hold on
scatter(circlestartingpoints(:,1), circlestartingpoints(:,2), 50, 'MarkerEdgeColor','red', 'MarkerFaceColor', 'red')
hold off
%% Our Problem
%% 4) We want to detect points belonging to the second circle in the middle.
% We look for points that have a distance less than 30 to the start-
% point and save them in a new Matrix called D
% Replace the start-point with a new one, the maximum of Matrix D.
% Find new points, go on til we dont find any new points nearby.
start(1,:) = circlestartingpoints(2,:)
D = circlestartingpoints(2,:);
distances = 1
while min(distances) < 30
dx = X(:,1) - start(1,1); dy = X(:,2) - start(1,2);
distances = sqrt(dx.^2+dy.^2);
indx = find(distances > 0 & distances < 30);
D = [D;X(indx,:)];
start(1,:) = max(D);
X(indx,:) = [];
end
D = unique(D, 'rows')
scatter(x, y, 20, 'MarkerEdgeColor', [0 .5 .5], 'MarkerFaceColor', [0 .7 .7])
axis equal
hold on
scatter(D(:,1), D(:,2), 'green')
function circlestartingpoints = detectstartingpoints(X0)
k = 1;
%Detect sarting points of circles
%Save minimum x-value in variable "circlestartingpoints"
%k is the group number of each circle
%
while isempty(X0) == 0
wert = min(X0(:,2));
findvalues = find(X0(:,2) < wert + 50)
circlestartingpoints(k,1) = min(X0(findvalues,1))
circlestartingpoints(k,2) = min(X0(findvalues,2))
X0(findvalues,:) = [];
k = k + 1;
end
end
function X0 = yintersectionappr(x, y,value)
x0 = find(x > (-1)*value & x < value); %Finde Punkte, die einen Schnittpunkt mit der y-Achse haben
X0 = unique([x(x0), y(x0)], 'rows');
end
I tried another code (see function circledatasearch()) for a test plot with some circles, it works very good but doesnt work for my matrix 'xycoords.txt'
yintersectionappr() and detectstartingpoints(X0) are the same functions as above.
%%Create Circles
R1 = 600; R2 = 900; x_c = 60; y_c = 60; mult = 2; mult1 = 5;
thetas1 = 0:pi/64:0.9*pi; thetas2 = 0:pi/64:0.75*pi;
xs1 = x_c + R1*cos(thetas1);
ys1 = y_c + R1*sin(thetas1);
xs2 = x_c + R2*cos(thetas2);
ys2 = y_c + R2*sin(thetas2);
xs1 = xs1+mult*normrnd(0,1)
ys1 = ys1+mult*normrnd(0,1)
xs2 = xs2+mult*normrnd(0,1)
ys2 = ys2+mult*normrnd(0,1)
xs3 = xs1+mult1*normrnd(0,1)
ys3 = ys1+mult1*normrnd(0,1)
x = [xs1,xs3, xs2]';
y = [ys1,ys3, ys2]';
scatter(x,y)
axis equal
%Find points
X = [x,y]; X = sortrows(X,2,"ascend");
X0 = yintersectionappr(x, y,20)
circlestartingpoints = detectstartingpoints(X0)
n = size(circlestartingpoints, 1)
circledatapoints = circledatasearch(X, circlestartingpoints(2,:))
xdata = circledatapoints(:,1);
ydata = circledatapoints(:,2);
function circledatapoints = circledatasearch(X, circlestartingpoints)
%Neue Nearestneighboursuche
circledatapoints(1,1) = circlestartingpoints(1,1);
circledatapoints(1,2) = circlestartingpoints(1,2);
start(1,1) = circlestartingpoints(1,1);
start(1,2) = circlestartingpoints(1,2);
f = 2;
while true
distance = sqrt((X(:,1)-start(1,1)).^2+(X(:,2)-start(1,2)).^2);
finddistances = find(distance < 50)
circledatapoints(f,1) = max(X(finddistances,1));
rownumber = find(X == circledatapoints(f,1));
circledatapoints(f,2) = X(rownumber,2);
start(1,1) = circledatapoints(f,1);
start(1,2) = circledatapoints(f,2);
if circledatapoints(f,:) == circledatapoints(f-1,:)
break
end
f = f+1;
end
end
Thanks in advance for your help! If something is unclear, please let me know :)

2 Comments

Whydon't you share only the points which are plotted in the attached figure..

Sign in to comment.

 Accepted Answer

I will use histogram, and get the indices.
clc; clear all ;
data = importdata("xycoords.txt") ;
x = data(:,1) ; y = data(:,2) ;
d = sqrt(x.^2+y.^2) ; % distance
b = 450:100:750 ; % make bins
[n,idx] = histc(d,b) ; % use histogram
plot(x,y,'.r')
hold on
plot(x(idx==2),y(idx==2),'.k')

6 Comments

WOW. Very nice idea. This works perfect. Thank you very much!
I have one last question: Is it possible to automize it for different sets of coordinates (different txt-files)?
is the range same for the data points?
no, they can differ. the circle segments can be widely different from matrix to matrix, but they are always quite parallel to each other. The matrix are always 1043x981 elements big
They can be theoretically like this (although this is an extreme example i think, because there is no intersection with the y-axis)
Thanks a lot for your time and effort!

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Asked:

on 24 Jun 2020

Edited:

on 24 Jun 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!