how to find points between boundaries

25 views (last 30 days)
Hi, I have a text file of data points taken from the coordinates of a point at time t and time t+10us, from this I can derive velocity and trajectory, a plot is attached. What I want to do with the data is figure out a way to work on the whole array at once without breaking it down into smaller arrays. The tricky bit is making sure you have the correct drops paired (t,t+10us), I have ways to do this but have not included it in the code below which I wanted to simplify as much as possible.
Plot shows the position of the points and the boundaries plotted between them, the boundaries demarcate something I am calling a 'slice'. So slice1 is empty,slice2 has 2 points,slice3 has 2 points,slice4 has 2 points, etc. What I don't know how to do simply (I found a very convoluted way of doing it) is how to use the vector B in such a way as to identify which points fall within the slice, ideally for anything that falls on or around the dashed boundary I would like to be able to see if it belonged to which of the neighbouring slices, for example if one slice had 2 points and its neighbour only 1 point then the boundary point should belong to slice 2. Any pointers?
Best regards
Steve
clear all
close all
clc
Ax=[1.6 1.2 2.2 2.7 2.4 3.3 3.33 4.8 4.9 5.7 5.1 6.6 6.2]';%simplified and reduced x data
Ay=[0.3 0.7 0.33 0.2 0.64 0.4 0.7 0.35 0.67 0.38 0.61 0.32 0.65]';%simplified and reduced y data
B=[0 1 2 3 4 5 6 7]';
scatter(Ax,Ay,'filled','b')
axis([0 7 0 0.8])
hold on
y1=get(gca,'ylim');
plot([B(:,1),B(:,1)],y1,'--r')
box on;grid minor
xlabel('x coordinates');
ylabel('y coordinates');
print('PointsFigure', '-dpng','-r0');
resultsVars={ 'SliceID','amount_of_points_in_slice','point1_Xcoord','point2_Xcoord','point1_Ycoord','point2_Ycoord',}
  2 Comments
KSSV
KSSV on 12 Mar 2018
YOu can use <= and >= inequalities to get the indices you want.
Stephen Devlin
Stephen Devlin on 12 Mar 2018
Yes KSSV, its figuring out how to do that on an array all at once.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 12 Mar 2018
Edited: Guillaume on 12 Mar 2018
So do you know which points are at t or t+10 or are you actually trying to find the displacement? If the latter, then a PTV (particle tracking velocimetry), or if the points are dense, PIV (particle image velocimetry) algorithm is what you need. These are very mature. I believe there's a FEX submission.
To answer your question, dividing Ay into slices is easily done with discretize:
sliceID = discretize(Ax, B);
Or, since you also want to know the number of points in each slice, with histcounts:
[bincount, ~, sliceID] = histcounts(Ax, B)
You can easily identify the borderline points:
tolerance = 0.1; %whatever you want it to be
[whichpoint, whichborder] = find(abs(Ax - B.') <= tolerance) %require R2016b or later
And move them to a different bin if you wish.
  8 Comments
Stephen Devlin
Stephen Devlin on 13 Mar 2018
So the anonymous function is taking the output from accumarray (for example '(v)') and making the larger cell array containing the output from accumarray?
Guillaume
Guillaume on 13 Mar 2018
r is just an input variable to the function. You can use any name you want for that variable, same as you can use any name you want for the inputs of a normal function. The anonymous function is equivalent to:
function unnamedoutput = anonymousfunction(r)
unnamedoutput = {sorteddata(r, 3:end);
end
with sorteddata captured when you create the function (this is the closure bit I linked to above).
Overall, the whole lot is equivalent to:
fun = @(r){sortedData(r,3:end)};
subs = sortedData(:, 7);
data = sortedData(:, 1);
uniquesubs = unique(subs);
Slice_uniq_OUT = cell(uniquesubs(end), 1);
for i = 1:numel(uniquesubs)
toaccumulate = data(subs == uniquesubs(i));
Slice_uniq_OUT(i) = fun(toaccumulate); %the r variable in the anonymous function receives toaccumulate
%without the anonymous function, this is equivalent to:
%Slice_uniq_OUT(i) = {sortedData(toaccumulate, 3:end)};
end
Your accumarray is more complicated than needed. The indirection throught the row index in column 1 is not needed. A simpler version would be:
Slice_uniq_OUT = accumarray(sortedData(:, 7), sortedData(:, 3:end), [], @(m) {m}); %the @(m) {m} simply wraps each submatrix into a cell array
Also note that it is often not necessary to split the main matrix into submatrices. Doing calculation by group is often easier on the whole matrix (using splitapply and similar)

Sign in to comment.

More Answers (0)

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!