-
Notifications
You must be signed in to change notification settings - Fork 1
/
roulette1.m
91 lines (82 loc) · 2.7 KB
/
roulette1.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
function [u, Md] = roulette1(func, funcd, M, u0, s)
%
% roulette1.m, (c) Matthew Roughan, 2013
%
% created: Mon Nov 25 2013
% author: Matthew Roughan
% email: [email protected]
%
% ROULETTE1
% Calculates the roulette of one curve with respect to the x-axis
% See
% "The General Theory of Roulettes", Gordon Walker, National Mathematics Magazine,
% Vol. 12, No.1, pp.21-26, 1937
% http://www.jstor.org/stable/3028504
%
% INPUTS:
% func = a function providing a parametric description of a curve
% i.e., points on the curve are defined by
% [x,y] = func(u)
% it is presumed that the point u0 corresponds to the origin
% and that the curve touches the origin at a tangent at this point
%
% funcd = derivatives of the function with respect to u
% this is used to numerically calculate arclengths
%
% M = the points we want to follow as the curve rolls
% M = Nx2 array
%
% u0 = parametric origin, i.e., we expect that
% x(u0) = 0
% y(u0) = 0
% dy/du(0) = 0 (the curve should be tangent to the x-axis at the origin)
% dx/du(0) ~= 0
%
% s = argument giving the points at which to calculate the roulette
% in terms of distance along the curve
%
% OUTPUTS:
% u = parameters that give curve at the arclenths s
% Md = [x_roulette, y_roulette] = a vector of points on the roulette
%
%
%
% either
% M is Nx2, N>1 and s is a scalar; or
% M = 1x2, and s is a vector
if (size(M,2) ~= 2)
error('M should be Nx2 for N points to be rolled');
end
if (size(M,1) > 1 & length(s) > 1)
error(' either calculate for multiple points M, or multiple s, but not both');
end
p = M(:,1);
q = M(:,2);
N = size(M,1);
s = s(:);
u = zeros(size(s));
% find points along the curve at distances s, where
% s = arclength(funcd, u)
% u = parameters that give arclengths from origin of s
options = optimset('MaxFunEvals', 1000);
for i=1:length(s)
f = @(t) ( s(i) - arclength(funcd, u0, t) );
u(i) = fzero(f, s(i), options);
end
% calculate points along the curve
points = func(u);
g = points(:,1);
G = points(:,2);
% calculate derivatives WRT u
derivatives = funcd(u);
dgdu = derivatives(:,1);
dGdu = derivatives(:,2);
% calculate derivatives WRT s, using the chain rule, and approximating
du = 1.0e-6;
duds = du ./ arclength(funcd, u, u+du);
dgds = dgdu .* duds';
dGds = dGdu .* duds';
% calculate the rolled points, when the rolling curve is a line
x = (p-g).*dgds + (q-G).*dGds + s;
y = -(p-g).*dGds + (q-G).*dgds;
Md = [x, y];