Matlab - Trace contour line between two different points
I have a set of points represented as a 2 row by n column matrix. These points开发者_如何学运维 make up a connected boundary or edge. I require a function that traces this contour from a start point P1 and stop at an end point P2. It also needs to be able trace the contour in a clockwise or anti-clockwise direction. I was wondering if this can be achieved by using some of Matlab's functions.
I have tried to write my own function but this was riddled with bugs and I have also tried using bwtraceboundary
and indexing however this has problematic results as the points within the matrix are not in the order that create the contour.
Thank you in advance for any help.
Btw, I have included a link to a plot of the set of points. It is half the outline of a hand.
The function would ideally trace the contour from ether the red star to the green triangle. Returning the points in order of traversal.
EDIT: This is perhaps a work around to a larger problem I am trying to solve but would it be possible to test if a point on the blue boundary edge is connected to the contour that is between either the red stars or green triangular points.
i.e. for a point on the blue boundary, if you were to trace the contour by hand from the left red asterixs to the green triangle the function would return true if the point is on the connected boundary between the two points and false otherwise.
alt text http://img717.imageshack.us/img717/9814/hand1.png
If the points are so close together, you should be able to do the trace by always looking for the next closest point in the list.
If the point were farther apart, the problem would not be solvable - imagine the five points where four are corners and one is in the center: what is the 'correct' way of tracing the line?
%%# create some points
npts = 100;
x = linspace(-1,1,100)'; %'
y = 1 - x.^2;
pts = [x,y];
%# shuffle the points
newOrder = randperm(npts);
pts = pts(newOrder,:);
%# find index of start, end point
startIdx = find(newOrder == 1);
endIdx = find(newOrder == npts);
%# this brings us to where you are - pts as a nx2 array
%# startIdx indicates the star, and endIdx indicates the triangle.
%# pre-assign output - traceIdx, which contains the ordered indices of the point on the trace
traceIdx = NaN(npts,1);
%# create distance matrix
distances = squareform(pdist(pts));
%# eliminate zero-distance along the diagonal, b/c we don't want points linking to themselves
distances(logical(eye(npts))) = NaN;
%# starting from startIdx: always find the closest next point, store in traceIdx,
%# check whether we've arrived at the end, and repeat if we haven't
done = false;
traceCt = 1;
traceIdx(1) = startIdx;
while ~done
%# find the index of the next, closest point
[dummy,newIdx] = min(distances(traceIdx(traceCt),:));
%# store new index and up the counter
traceCt = traceCt + 1;
traceIdx(traceCt) = newIdx;
%# check whether we're done
if newIdx == endIdx
done = true;
else
%# mask the backward distance so that there's no turning back
distances(newIdx,traceIdx(traceCt-1)) = NaN;
end %# if
end %# while ~done
%# remove NaNs
traceIdx(~isfinite(traceIdx)) = [];
%# plot result with a line connecting the dots to demonstrate that everything went well.
figure,
plot(pts(traceIdx,1),pts(traceIdx,2),'-o')
hold on,
plot(pts(startIdx,1),pts(startIdx,2),'*r')
plot(pts(endIdx,1),pts(endIdx,2),'>g')
精彩评论