How to find zero on plot?
20 views (last 30 days)
Show older comments
In attachment, the blue line represents the right heel marker walking up the stairs. The orange line is the derivative of the position of the heel, so it represents the speed of the heel marker. I need to know where the heel touches the ground, so when the speed of the heel is zero. How can I find these points?
2 Comments
Answers (3)
Image Analyst
on 27 Dec 2014
Edited: Image Analyst
on 27 Dec 2014
Try this
zeroSpeedIndexes = orangeSignal = 0; % logical array of where speed is zero.
To be more robust, you might want to check if it's less than some small number (in case it never hits exactly zero), and then find the centroid, or first index, of those indexes.
zeroSpeedIndexes = abs(orangeSignal) <= someSmallNumber;
For example, let's say the speed is around 0 to 10 when the heel is moving, but sometimes the speed never quite hits zero but instead bounces around 0.05 or whatever. So someSmallNumber would be 0.05. This is more robust than just checking for an exact zero.
To get actual indexes ( in case you need them but probably don't) use find():
linearIndexes = find(zeroSpeedIndexes);
Star Strider
on 27 Dec 2014
Going back to your Question earlier:
d = matfile('Sam_RHEE.mat');
RH = d.RHEE; % Signal Vector
T = 0:size(RH)-1; % Time Vector
dRH = gradient(RH,T); % Derivative (w.r.t. T, ‘T’ not required)
dRHcs = dRH .* circshift(dRH, [-1 0]);
dRHzx = find(dRHcs < 0);
for k1 = 1:size(dRHzx,1)-1
dRH0(k1) = interp1(dRH(dRHzx(k1):dRHzx(k1)+1), T(dRHzx(k1):dRHzx(k1)+1), 0);
end
figure(1)
plot(T, RH)
hold on
plot(T, dRH*100)
yl = ylim;
plot([dRH0; dRH0], [ones(1,size(dRH0,2))*yl(1); ones(1,size(dRH0,2))*yl(2)], '-g')
hold off
grid
This finds the points where the derivative ‘dRH’ crosses zero (which is what I believe you want) in the ‘dHR0’ vector, and then plots vertical green lines at those points, so you can match the derivative and the ‘RHEE’ signals at those times.
The plot:
4 Comments
Star Strider
on 28 Dec 2014
My pleasure!
Line-by-line:
1. dRHcs = dRH .* circshift(dRH, [-1 0]);
This takes ‘dRH’ and multiplies it by a one-position-circularly-shifted version of itself. (See the documentation for circshift for details.) All the products that have the same sign, whether positive or negative, will have positive products. If adjacent elements have opposite signs, that product will be negative.
2. dRHzx = find(dRHcs <= 0);
This provides the indices of the negative or zero elements of the multiplication in 1.
3. The for loop calculates the exact zero-crossings using adjacent elements of ‘dRHzx’ and the interp1 function. Note that the arguments to it are reversed from the usual, because the desired output is the value where ‘dRH’ is zero. It has to do this in a loop because it takes each estimated zero-crossing in turn and calculates the exact values for it. (It does not include the last estimated zero-crossing, because using circshift can create an artefactual zero-crossing at the end of the vector. It is best not to include it.)
4. The plot call looks more complicated than it is. The plot function requires at least two independent and two dependent variable values to plot a line. The usual way to plot a series of vertical lines (and the way I did it here), is to create a (2xN) matrix of different x-coordinates and a matching (2xN) matrix of essentially the same y-coordinates, so that here a vertical (green) line is plotted at every zero-crossing for the ‘dRH’ variable. If you want to see how it works in detail, create these:
xmat = [dRH0; dRH0];
ymat = [ones(1,size(dRH0,2))*yl(1); ones(1,size(dRH0,2))*yl(2)];
after the plot (because plot creates the ‘yl’ vector), and look at them. (The same idea — with the appropriate changes — works if you want to plot horizontal lines.)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!