-
Notifications
You must be signed in to change notification settings - Fork 3
/
GetEvenSpacing.m
executable file
·138 lines (122 loc) · 4.74 KB
/
GetEvenSpacing.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
% Get a range of indices that give evenly spaced data points to downsample
%
%------------------------------------------------------------------------------
% Copyright (c) 2012, Tyler Voskuilen
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in
% the documentation and/or other materials provided with the
% distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
% PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
%------------------------------------------------------------------------------
%
% Required Inputs:
% x A vector of x data
% y A vector of y data
% N The number of points to subdivide the vector into for plotting
%
% Optional Inputs:
% x_mode (optional) - Either 'Log' or 'Linear' (default) to scale the
% resulting x range for log plotting
% y_mode (optional) - Either 'Log' or 'Linear' (default) to scale the
% resulting y range for log plotting
% x_range (optional)- Length to scale 'x' over (defaults to min/max)
% y_range (optional)- Length to scale 'y' over (defaults to min/max)
%
% For example, if 'time' and 'F' are dense vectors of the
% same length, you can subdivide them into 50 points with:
%
% r = GetEvenSpacing(time, F, 50);
% plot(time,F,'-r');
% hold on;
% plot(time(r), F(r), 'ok');
%
% so their markers are visible over the existing data
%
%------------------------------------------------------------------------------
function range = GetEvenSpacing(x, y, N, x_mode, y_mode, x_range, y_range)
% No "up-sampling" considered
if N > length(x)
range = ones(size(x));
return
end
%Set x_mode and y_mode to 'Linear' if not specified
if ~exist('x_mode','var')
x_mode = 'Linear';
end
if ~exist('y_mode','var')
y_mode = 'Linear';
end
%Set x and y plot ranges
if ~exist('x_range','var')
x_range = [min(x) max(x)];
end
if ~exist('y_range','var')
y_range = [min(y) max(y)];
end
% Make xs0 and ys0 that vary over the same order of magnitude
if strcmp(x_mode,'Log') || strcmp(x_mode,'log')
xs0 = log((x - x_range(1)) ./ (x_range(2) - x_range(1)));
else
xs0 = (x - x_range(1)) ./ (x_range(2) - x_range(1));
end
if strcmp(y_mode,'Log') || strcmp(y_mode,'log')
ys0 = log((y - y_range(1)) ./ (y_range(2) - y_range(1)));
else
ys0 = (y - y_range(1)) ./ (y_range(2) - y_range(1));
end
%Make a coarse spline of the line to find its real, non-noisy length
spl = 1:floor(length(xs0)/50):length(xs0);
xss0 = xs0(spl);
yss0 = spline(xs0,ys0,xss0);
ssz = size(xss0);
if ssz(1) > 1
xss1 = [xss0(1); xss0(1:end-1)];
yss1 = [yss0(1); yss0(1:end-1)];
else
xss1 = [xss0(1) xss0(1:end-1)];
yss1 = [yss0(1) yss0(1:end-1)];
end
dss = sqrt((xss0-xss1).^2 + (yss0-yss1).^2);
ss = cumsum(dss);
yexit = find(xss0>1,1,'first');
xexit = find(yss0>1,1,'first');
if isempty(yexit)
yexit = length(yss0);
end
if isempty(xexit)
xexit = length(xss0);
end
exit_pt = min([yexit xexit]);
span = max(ss(1:exit_pt)) / N;
%Subdivide path into N segments and get transition points
pivots = zeros(size(xs0));
pivots(1) = 1;
lastpt = 1;
for i=2:length(xs0)
del = sqrt((xs0(i)-xs0(lastpt)).^2 + (ys0(i)-ys0(lastpt)).^2);
if del > span
pivots(i) = 1;
lastpt = i;
end
end
range = find(pivots==1);