-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcurvspace.m
More file actions
128 lines (106 loc) · 3.27 KB
/
curvspace.m
File metadata and controls
128 lines (106 loc) · 3.27 KB
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
function q = curvspace(p,N)
% CURVSPACE Evenly spaced points along an existing curve in 2D or 3D.
% CURVSPACE(P,N) generates N points that interpolates a curve
% (represented by a set of points) with an equal spacing. Each
% row of P defines a point, which means that P should be a n x 2
% (2D) or a n x 3 (3D) matrix.
%
% (Example)
% x = -2*pi:0.5:2*pi;
% y = 10*sin(x);
% z = linspace(0,10,length(x));
% N = 50;
% p = [x',y',z'];
% q = curvspace(p,N);
% figure;
% plot3(p(:,1),p(:,2),p(:,3),'*b',q(:,1),q(:,2),q(:,3),'.r');
% axis equal;
% legend('Original Points','Interpolated Points');
%
% See also LINSPACE.
%
% 22 Mar 2005, Yo Fukushima
%% initial settings %%
currentpt = p(1,:); % current point
indfirst = 2; % index of the most closest point in p from curpt
len = size(p,1); % length of p
q = currentpt; % output point
k = 0;
%% distance between points in p %%
for k0 = 1:len-1
dist_bet_pts(k0) = distance(p(k0,:),p(k0+1,:));
end
totaldist = sum(dist_bet_pts);
%% interval %%
intv = totaldist./(N-1);
%% iteration %%
for k = 1:N-1
newpt = []; distsum = 0;
ptnow = currentpt;
kk = 0;
pttarget = p(indfirst,:);
remainder = intv; % remainder of distance that should be accumulated
while isempty(newpt)
% calculate the distance from active point to the most
% closest point in p
disttmp = distance(ptnow,pttarget);
distsum = distsum + disttmp;
% if distance is enough, generate newpt. else, accumulate
% distance
if distsum >= intv
newpt = interpintv(ptnow,pttarget,remainder);
else
remainder = remainder - disttmp;
ptnow = pttarget;
kk = kk + 1;
if indfirst+kk > len
newpt = p(len,:);
else
pttarget = p(indfirst+kk,:);
end
end
end
% add to the output points
q = [q; newpt];
% update currentpt and indfirst
currentpt = newpt;
indfirst = indfirst + kk;
end
%%%%%%%%%%%%%%%%%%%%%%%%%
%% SUBFUNCTIONS %%
%%%%%%%%%%%%%%%%%%%%%%%%%
function l = distance(x,y)
% DISTANCE Calculate the distance.
% DISTANCE(X,Y) calculates the distance between two
% points X and Y. X should be a 1 x 2 (2D) or a 1 x 3 (3D)
% vector. Y should be n x 2 matrix (for 2D), or n x 3 matrix
% (for 3D), where n is the number of points. When n > 1,
% distance between X and all the points in Y are returned.
%
% (Example)
% x = [1 1 1];
% y = [1+sqrt(3) 2 1];
% l = distance(x,y)
%
% 11 Mar 2005, Yo Fukushima
%% calculate distance %%
if size(x,2) == 2
l = sqrt((x(1)-y(:,1)).^2+(x(2)-y(:,2)).^2);
elseif size(x,2) == 3
l = sqrt((x(1)-y(:,1)).^2+(x(2)-y(:,2)).^2+(x(3)-y(:,3)).^2);
else
error('Number of dimensions should be 2 or 3.');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function newpt = interpintv(pt1,pt2,intv)
% Generate a point between pt1 and pt2 in such a way that
% the distance between pt1 and new point is intv.
% pt1 and pt2 should be 1x3 or 1x2 vector.
dirvec = pt2 - pt1;
dirvec = dirvec./norm(dirvec);
l = dirvec(1); m = dirvec(2);
newpt = [intv*l+pt1(1),intv*m+pt1(2)];
if length(pt1) == 3
n = dirvec(3);
newpt = [newpt,intv*n+pt1(3)];
end