elbow_finder.m 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. function [idxOfBestPoint] = elbow_finder(curve,verbose)
  2. if nargin <2
  3. verbose = 0;
  4. end
  5. %# get coordinates of all the points
  6. nPoints = length(curve);
  7. allCoord = [1:nPoints;curve]'; %'# SO formatting
  8. %# pull out first point
  9. firstPoint = allCoord(1,:);
  10. %# get vector between first and last point - this is the line
  11. lineVec = allCoord(end,:) - firstPoint;
  12. %# normalize the line vector
  13. lineVecN = lineVec / sqrt(sum(lineVec.^2));
  14. %# find the distance from each point to the line:
  15. %# vector between all points and first point
  16. vecFromFirst = bsxfun(@minus, allCoord, firstPoint);
  17. %# To calculate the distance to the line, we split vecFromFirst into two
  18. %# components, one that is parallel to the line and one that is perpendicular
  19. %# Then, we take the norm of the part that is perpendicular to the line and
  20. %# get the distance.
  21. %# We find the vector parallel to the line by projecting vecFromFirst onto
  22. %# the line. The perpendicular vector is vecFromFirst - vecFromFirstParallel
  23. %# We project vecFromFirst by taking the scalar product of the vector with
  24. %# the unit vector that points in the direction of the line (this gives us
  25. %# the length of the projection of vecFromFirst onto the line). If we
  26. %# multiply the scalar product by the unit vector, we have vecFromFirstParallel
  27. scalarProduct = dot(vecFromFirst, repmat(lineVecN,nPoints,1), 2);
  28. vecFromFirstParallel = scalarProduct * lineVecN;
  29. vecToLine = vecFromFirst - vecFromFirstParallel;
  30. %# distance to line is the norm of vecToLine
  31. distToLine = sqrt(sum(vecToLine.^2,2));
  32. %# now all you need is to find the maximum
  33. [~,idxOfBestPoint] = max(distToLine);
  34. %# plot the distance to the line
  35. if verbose
  36. figure('Name','distance from curve to line'), plot(distToLine)
  37. %# plot
  38. figure, plot(curve)
  39. hold on
  40. plot(allCoord(idxOfBestPoint,1), allCoord(idxOfBestPoint,2), 'or')
  41. end
  42. end