1 %% Copyright (c) 2012 Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
3 %% This program is free software: you can redistribute it and/or modify
4 %% it under the terms of the GNU General Public License as published by
5 %% the Free Software Foundation, either version 3 of the License, or
8 %% This program is distributed in the hope that it will be useful,
9 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
10 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 %% GNU General Public License for more details.
13 %% You should have received a copy of the GNU General Public License
14 %% along with this program. If not, see <http://www.gnu.org/licenses/>.
17 %% @deftypefn {Function File} {[@var{tangent},@var{inner}] = } beltproblem (@var{c}, @var{r})
18 %% Finds the four lines tangent to two circles with given centers and radii.
20 %% The function solves the belt problem in 2D for circles with center @var{c} and
26 %% 2-by-2 matrix containig coordinates of the centers of the circles; one row per circle.
28 %% 2-by-1 vector with the radii of the circles.
34 %% 4-by-4 matrix with the points of tangency. Each row describes a segment(edge).
36 %% 4-by-2 vector with the point of intersection of the inner tangents (crossed belts)
37 %% with the segment that joins the centers of the two circles. If
38 %% the i-th edge is not an inner tangent then @code{inner(i,:)=[NaN,NaN]}.
46 %% [T inner] = beltproblem(c,r)
48 %% -0.68516 0.72839 1.34258 2.63581
49 %% 0.98516 0.17161 0.50742 2.91419
50 %% 0.98675 -0.16225 1.49338 2.91888
51 %% -0.88675 0.46225 0.55663 3.23112
64 function [edgeTan inner] = beltproblem(c,r)
66 x0 = [c(1,1) c(1,2) c(2,1) c(2,2)];
69 middleEdge = createEdge(c(1,:),c(2,:));
71 ind0 = [1 0 1 0; 0 1 1 0; 1 1 1 0; -1 0 1 0; 0 -1 1 0; -1 -1 1 0;...
72 1 0 0 1; 0 1 0 1; 1 1 0 1; -1 0 0 1; 0 -1 0 1; -1 -1 0 1;...
73 1 0 1 1; 0 1 1 1; 1 1 1 1; -1 0 1 1; 0 -1 1 1; -1 -1 1 1;...
74 1 0 -1 0; 0 1 -1 0; 1 1 -1 0; -1 0 -1 0; 0 -1 -1 0; -1 -1 -1 0;...
75 1 0 0 -1; 0 1 0 -1; 1 1 0 -1; -1 0 0 -1; 0 -1 0 -1; -1 -1 0 -1;...
76 1 0 -1 -1; 0 1 -1 -1; 1 1 -1 -1; -1 0 -1 -1; 0 -1 -1 -1; -1 -1 -1 -1];
84 %% Solve for 2 different lines
85 while nSol<4 && i<nInit
86 ind = find(ind0(ir(i),:)~=0);
88 x(ind)=x(ind)+r0(ind);
89 [sol f0 nev]= fsolve(@(x)belt(x,c,r),x);
95 notequal(j) = all(abs(edgeTan(j,:)-sol) > 1e-6);
99 edgeTan(nSol,:) = createEdge(sol(1:2),sol(3:4));
101 inner(nSol,:) = intersectEdges(middleEdge,edgeTan(nSol,:));
109 function res = belt(x,c,r)
112 res(1,1) = (x(3:4) - c(2,1:2))*(x(3:4) - x(1:2))';
113 res(2,1) = (x(1:2) - c(1,1:2))*(x(3:4) - x(1:2))';
114 res(3,1) = sumsq(x(1:2) - c(1,1:2)) - r(1)^2;
115 res(4,1) = sumsq(x(3:4) - c(2,1:2)) - r(2)^2;
122 %! [T inner] = beltproblem(c,r)
127 %! set(h(find(~isnan(inner(:,1)))),'color','r');
128 %! set(h,'linewidth',2);
130 %! drawCircle([c(1,:) r(1); c(2,:) r(2)],'linewidth',2);
134 %! % -------------------------------------------------------------------
135 %! % The circles with the tangents edges are plotted. The solution with
136 %! % crossed belts (inner tangets) is shown in red.