Search code examples
matlabgeometryoctavenumerical-methods

Find a circle circle tangent using an iterative, numerical, method


circle circle tangents

Given: centers and radii of two circles

My problem is that I cannot figure out how to use a numerical method to find a circle circle tangent. Using http://mathworld.wolfram.com/Circle-CircleTangents.html I would have some idea of how to solve it by hand but no idea how to do so using matlab/octave.

It is setting up the problem that causes me difficulties. Namely creating the system of equations. On the website above they use the fact that the dot product between the line from the center to the tangent-point is perpendicular to the tangential line. However, I have no idea of how I would translate this into my model. If I used matlab's "dot" function, how would I set up the Jacobian matrix?


Solution

  • Using MATLAB built-in functions

    The simplest way to do it would be to define the function as it is, then use the fsolve() function. For example (the code is not tested):

    function y = cctang(t)
        %t is a 1-by-4 line vector (first two members = t1, last two members = t2)
        %y is a 1-by-4 vector
    
        %Initialization of centers and radii
        x1 = [0 0]; r1=4;
        x2 = [1 1]; r2=0.5;
    
        y= zeros(1, 4);
    
        y(1) = ( t(3:4) - x2) * ( t(3:4) - t(1:2))';
        y(2) = ( t(1:2) - x1) * ( t(3:4) - t(1:2))';
        y(3) = norm(t(1:2)-x1)^2 - r1^2;
        y(4) = norm(t(3:4)-x2)^2 - r2^2;
    
    end
    

    And then the execution:

    t0 = [0 0 1 1];
    solution = fsolve(@cctang,t0);
    

    Using custom iterative function

    If you want to build everything from scratch, you can build a custom Jacobian function and input it to the solving function you gave in the question. The Jacobian function should look like:

    function  J = myJacobian(t)
        %returns a 4-by-4 matrix
        x1 = [0 0]; r1=4;
        x2 = [1 1]; r2=0.5;
    
        J = zeros(4,4);
    
        J(1,:) = [ x2(1)-t(3), x2(2)-t(4), 2*t(3)-x2(1), 2*t(4)-x2(2)];
        %etc...
    end
    

    Using Symbolic Toolbox

    Much of the "hard work" in the previous method comes from the fact that you need to compute the derivatives numerically and manually. Using the Symbolic Toolbox, you can symbolically define the function, and then use the built-in jacobian() function to compute the Jacobian matrix.

    Those would be the input to your custom numeric solving function. At each iteration you should substitute the symbolic variables with the actual numeric values (see subs()).

    This will make your code much more general and less sensitive to human errors (for example, what is the probability I made a mistake in the one derivative I computed in the last block of code?).