## Copyright (C) 2012-2019 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## Author: Juan Pablo Carbajal ## Updated: 2019-05-14 ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{tangent},@var{inner}] = } beltProblem (@var{c}, @var{r}) ## Finds the four lines tangent to two circles with given centers and radii. ## ## The function solves the belt problem in 2D for circles with center @var{c} and ## radii @var{r}. ## ## @strong{INPUT} ## @table @var ## @item c ## 2-by-2 matrix containig coordinates of the centers of the circles; one row per circle. ## @item r ## 2-by-1 vector with the radii of the circles. ##@end table ## ## @strong{OUPUT} ## @table @var ## @item tangent ## 4-by-4 matrix with the points of tangency. Each row describes a segment(edge). ## @item inner ## 4-by-2 vector with the point of intersection of the inner tangents (crossed belts) ## with the segment that joins the centers of the two circles. If ## the i-th edge is not an inner tangent then @code{inner(i,:)=[NaN,NaN]}. ## @end table ## ## Example: ## ## @example ## c = [0 0;1 3]; ## r = [1 0.5]; ## [T inner] = beltProblem(c,r) ## @result{} T = ## -0.68516 0.72839 1.34258 2.63581 ## 0.98516 0.17161 0.50742 2.91419 ## 0.98675 -0.16225 1.49338 2.91888 ## -0.88675 0.46225 0.55663 3.23112 ## ## @result{} inner = ## 0.66667 2.00000 ## 0.66667 2.00000 ## NaN NaN ## NaN NaN ## ## @end example ## ## @seealso{edges2d} ## @end deftypefn function [edgeTan inner] = beltProblem(c,r) x0 = [c(1,1) c(1,2) c(2,1) c(2,2)]; r0 = r([1 1 2 2]); middleEdge = createEdge(c(1,:),c(2,:)); 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;... 1 0 0 1; 0 1 0 1; 1 1 0 1; -1 0 0 1; 0 -1 0 1; -1 -1 0 1;... 1 0 1 1; 0 1 1 1; 1 1 1 1; -1 0 1 1; 0 -1 1 1; -1 -1 1 1;... 1 0 -1 0; 0 1 -1 0; 1 1 -1 0; -1 0 -1 0; 0 -1 -1 0; -1 -1 -1 0;... 1 0 0 -1; 0 1 0 -1; 1 1 0 -1; -1 0 0 -1; 0 -1 0 -1; -1 -1 0 -1;... 1 0 -1 -1; 0 1 -1 -1; 1 1 -1 -1; -1 0 -1 -1; 0 -1 -1 -1; -1 -1 -1 -1]; nInit = size(ind0,1); ir = randperm(nInit); edgeTan = zeros(4,4); inner = zeros(4,2); nSol = 0; i=1; ## Solve for 2 different lines while nSol<4 && i 1e-6); end if all(notequal) nSol = nSol+1; edgeTan(nSol,:) = createEdge(sol(1:2),sol(3:4)); # Find innerTangent inner(nSol,:) = intersectEdges(middleEdge,edgeTan(nSol,:)); end i = i+1; end # Sort to avoid random order of results [~, order] = sort (sumsq (inner, 2)); inner = inner(order,:); edgeTan = edgeTan(order,:); endfunction function res = belt(x,c,r) res = zeros(4,1); res(1,1) = (x(3:4) - c(2,1:2))*(x(3:4) - x(1:2))'; res(2,1) = (x(1:2) - c(1,1:2))*(x(3:4) - x(1:2))'; res(3,1) = sumsq(x(1:2) - c(1,1:2)) - r(1)^2; res(4,1) = sumsq(x(3:4) - c(2,1:2)) - r(2)^2; end %!demo %! c = [0 0;1 3]; %! r = [1 0.5]; %! [T inner] = beltProblem(c,r) %! %! figure(1) %! clf %! hold on %! h = drawEdge (T); %! set(h(find(~isnan(inner(:,1)))),'color','m'); %! set(h,'linewidth',2); %! hold on %! drawCircle([c(1,:) r(1); c(2,:) r(2)],'linewidth',2); %! axis tight %! axis equal %! %! # ------------------------------------------------------------------- %! # The circles with the tangents edges are plotted. The solution with %! # crossed belts (inner tangets) is shown in red.