**You are now following this question**

- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.

# how to plot tangent line from specified point to a circle ?

28 views (last 30 days)

Show older comments

Dear Friends,

There is a specified point which is;

[X , Y]

And there is a circle which radius is

r

Before I asked, I searched for the answer and I found something. However, the codes that I found did not work for my program and I don't know why. so how can I plot a tangent line from this point to this circle with 'r' radius. Thanks

##### 2 Comments

dpb
on 3 Dec 2015

Ender Rencuzogullari
on 3 Dec 2015

sorry about missing information. the circle's center is positioned at

[0 , 0]

### Accepted Answer

Star Strider
on 3 Dec 2015

See if this does what you want:

a = linspace(0, 2*pi); % Assign Angle Vector

r = 2; % Radius

ctr = [2 3]; % Centre

x = ctr(1) + r.*cos(a); % Circle ‘x’ Vector

y = ctr(2) + r.*sin(a); % Circle ‘y’ Vector

dxda = -r.*sin(a); % Derivative

dyda = r.*cos(a); % Derivative

dydx = dyda./dxda; % Slope Of Tangent

N = 21; % Choose Point On Circle (As Index)

point = [x(N) y(N)]; % Define Point

intcpt = point(2) - dydx(N).*point(1); % Calculate Intercept

xvct = point(1)-1:point(1)+1; % ‘x’ Vecor For Tangent

tngt = dydx(N).*xvct + intcpt; % Calculate Tantent

figure(1)

plot(x, y) % Plot Circle

hold on

plot(point(1), point(2), 'gp') % Plot Point

plot(xvct, tngt) % Plot Tangent At Point

hold off

axis equal

grid

##### 13 Comments

Ender Rencuzogullari
on 3 Dec 2015

Edited: Ender Rencuzogullari
on 3 Dec 2015

Sir, probably I did not explained my question good enough. My bad. There is a point out of the circle. The point is

[X(1), Y(1)].

And then, there is a circle which its radius ' r ' and coordinate of center is at

[0 , 0]

I have tried your code and I got this result in attached image;

There existed a point and a tangent line on circle. However, I need to plot a tangent line from [X(1) , Y(1)] to this [0 , 0] centered circle with radius of r. As an image;

In deed, I want to connect this point with the circle as tangentially. When the line touches the circle, it must stop.

Star Strider
on 4 Dec 2015

Edited: Star Strider
on 4 Dec 2015

Here you go:

% % % % % PLOT TANGENTS TO A CIRCLE FROM A POINT OUTSIDE THE CIRCLE —

% % Reference: https://en.wikipedia.org/wiki/Law_of_cosines

a = linspace(0, 2*pi); % Assign Angle Vector

r = 2; % Circle Radius (‘a’)

ctr = [0.0 0.0]; % Circle Centre

x = ctr(1) + r.*cos(a); % Circle ‘x’ Vector

y = ctr(2) + r.*sin(a); % Circle ‘y’ Vector

XY = [-5.5 3.5]; % Point Outside Circle From Which Tangents Are Plotted

c = hypot(XY(1)-ctr(1),XY(2)-ctr(2));

if c <= r

error('\n\tPOINT ON OR WITHIN CIRCLE RADIUS —> NO TANGENTS POSSIBLE!\n\n')

end

b = sqrt(c.^2 - r.^2); % See Wikipedia Reference

alfa = acos((r.^2 - b.^2 - c.^2)./(-2*b*c)); % See Wikipedia Reference

beta = acos((b.^2 - r.^2 - c.^2)./(-2*r*c)); % See Wikipedia Reference

pt_ctr_angl = atan2(-(XY(2)-ctr(2)),-(XY(1)-ctr(1))); % Angle From ‘Point’ To Circle Centre

alfac = [pt_ctr_angl + alfa; pt_ctr_angl - alfa]; % Angles From ‘Point’ For Tangents

xtng = XY(1) + [b.*cos(alfac(1)); b.*cos(alfac(2))]; % Tangent Point ‘x’ Coordinates

ytng = XY(2) + [b.*sin(alfac(1)); b.*sin(alfac(2))]; % Tangent Point ‘y’ Coordinates

figure(1)

plot(x, y) % Plot Circle

hold on

plot(XY(1), XY(2), 'bp') % Plot ‘Point’

plot([XY(1) xtng(1)], [XY(2) ytng(1)]) % Plot Tangents

plot([XY(1) xtng(2)], [XY(2) ytng(2)]) % Plot Tangents

hold off

grid

axis equal % Prevent Warping

Ender Rencuzogullari
on 4 Dec 2015

Edited: Ender Rencuzogullari
on 4 Dec 2015

Sir, Thanks a lot. It works but there existed two problems in my code. such as;

first problem is: b becamed a complex number so alfa, beta, xtng, ytng are.

second problem is : Actually, c = 75.00005872 and r=75 but program takes c = 75.0000 and r = 75.0000 so it seems the same point. But actually they are not the same. (X(1) and Y(1) values are founding with 4 digits after decimal. I tried to change whole program format for more digits but I could not.)

So program takes only 4 digits after decimal for c. naturally, program does not plot tangent line because of this reason. I tried to use;

But I could not get the result that I desired. I changed even the format as "long" from preferences options. I know I asked too much and really sorry about it. However, I think that is the my main and last problem about not plotting the tangent line and becoming of b is a complex number. Sir, If you want to see the results, This is my whole program;

When run the program, inputs are respectively: 4, 30 , 20, 1, 1.25 , 0.2 , 100 , 100

"c is inside the figure(1)"

%INVOLUTE COORDINATES

module='input the module > Module = ';

m=input(module);

numberofteeth='input the number of teeth > Teeth Number = ';

T=input(numberofteeth);

pressure_angle='input the pressure angle at pitch radius > Pressure Angle(deg) = ';

pre_ang=input(pressure_angle);

addendum_coefficient='input the addendum coefficient > a = ';

a_c=input(addendum_coefficient);

dedendum='input the dedendum coefficient > b_c= ';

b_c=input(dedendum);

h_t_r_c='input the Hob Tip Radius Coefficient > HTRC= ';

HTRC=input(h_t_r_c);

%addendum

a=a_c*m;

%dedendum

b = b_c*m;

% Evaluate the "Pitch Radius"

rp = (m*T)/2;

% Evaluate the "Base Radius"

rb = rp*cos(deg2rad(pre_ang));

%Evaluate the "Root Radius"

rr = rp-b;

% Evaluate the "Tip Radius"

rt = rp + a;

% Evaluate the "Circular Pitch Tooth Thickness"

cptt = (pi*m)/2;

% Evaluate the "Involute Angle at pitch point (theta)"

theta_pitch = tan(deg2rad(pre_ang))- deg2rad(pre_ang);

prompt= 'input the slice number on involute curve= ';

n_slice=input(prompt);

prompt='input the point number of trochoid > point number= ';

PointNumberTrochoid=input(prompt);

R=linspace(rb,rt,n_slice);

% vector length N between [rb rt]

% Evaluate the pressure angle at Ri

theta = acos(rb./R);

%Evaluate the involute angle at Ri

inv_ang = tan(theta)-theta;

% Evaluate the Circular Tooth Thickness at Ri

ctt = 2*R.*(0.5*cptt./rp + theta_pitch-inv_ang);

B_involute = 0.5*ctt./R;

X_inv = R.*sin(B_involute);

Y_inv = R.*cos(B_involute);

% TROCHOID COORDINATES

c_pitch = pi*m; %circular pitch

r_hob_tip = HTRC*m; %hob tip radius

Emax= 25*pi/180;

B= b-r_hob_tip;

L= (c_pitch/4)-(B*tan(deg2rad(pre_ang)))-(r_hob_tip/cos(deg2rad(pre_ang)));

W= ((c_pitch/2)-L)/rp;

E=linspace(0,Emax,PointNumberTrochoid);

Xz = (rp.*E.*cos(E))-((rp-B).*sin(E));

Yz = ((rp-B).*cos(E))+(rp.*E.*sin(E));

dXz= -(rp.*E.*sin(E))+(B.*cos(E));

dYz= (rp.*E.*cos(E))+(B.*sin(E));

A= atan(dXz./dYz);

if E==0

A=pi/2;

end

Xt = Xz+(r_hob_tip*cos(A));

Yt = Yz-(r_hob_tip*sin(A));

X = (Yt.*sin(W))-(Xt.*cos(W));

Y = (Yt.*cos(W))+(Xt.*sin(W));

%When you grow an array incrementally as you are doing with DE, MATLAB is forced to reallocate the entire array at EVERY iteration,

%copying over the entire mess just to add ONE element.

%This will cause the operation to get slower, and the time required will grow quadratically.

%SO it will get SLOW. You know in the end EXACTLY how large DE will be. So just add ONE extra line before the loop.

%This essentially creates the array in advance, filling it with zeros.

%It need no longer reallocated at each iteration, because it will no longer need to change size at every step.

%Much of the time, preallocation is not needed. MATLAB is not a language where you need to initialize/allocate every array.

%Variables that are scalars, and will remain so are never an issue. It is only when an array is dynamically grown that preallocation is important.

%A problem arises when you don't know the final size of your array. Even there, there are tricks that one can do.

%I posted a "submission to the FEX" long ago that allows the user to store information in a form that can be more efficiently grown, then at the end, you can unpack the object into a regular array.

DE = zeros(length(X),length(X_inv)); % Preallocation for speed

for k1 =1: length(X)

for k2 =1: length(X_inv)

DE(k1,k2)= hypot(X(k1)-X_inv(k2), Y(k1)-Y_inv(k2)); % Euclidean Distance

end

end

[DEmin,ix] = min(DE(:));

[K1,K2] = ind2sub(size(DE),ix);

nxs_idx= find( Y <= Y_inv(K2)); % Only Retain Indices Of ‘Y axis value of trochoid’ Points >= Closest Point

% Those first three fprintf commands,below, show the "Nearest Point" on Trochoid curve

% to point on Involute curve. The nearest point on trochoid might be at any

% coordinate. Coordinate of this point should be found because we need to be aware of

% whether its coordinate is outside of the involute curve or not. If the nearest point of Trochoid is outside,

% there will be problem about shape of tooth. Thus, we can make the program executes the limit condition due to its coordinate

% about specifying to coordinates of those points for plotting graph.

% However, If there needs to arise to see the difference between distance of

% actual nearest points and the distance of nearest points under the

% limitation which will be encoded ,at further steps, delete the comment "%" commands and run.

%fprintf(1,'\nNearest Points:\n\tDistance = %.4f mm\n', DEmin)

%fprintf(1,'\t\tX(%d), Y(%d) \t\t\t= %.4f mm, %.4f mm\n',K1, K1, X(K1), Y(K1))

%fprintf(1,'\t\tX_inv(%d), Y_inv(%d) \t= %.4f mm , %.4f mm \n', K2, K2, X_inv(K2), Y_inv(K2))

D_E = zeros(length(X(nxs_idx)),length(X_inv));

for i=1: length(X(nxs_idx))

for j=1: length(X_inv)

D_E(i,j) = hypot(X(i)-X_inv(j), Y(i)-Y_inv(j)); % Eucledian Distance

end

end

[D_Emin,i_x] = min(D_E(:));

[K_1,K_2] = ind2sub(size(D_E),i_x);

Qpt = [X(K_1) Y(K_1)]; % Nearest (X,Y) Point

Q_invpt = [X_inv(K2) Y_inv(K2)]; % Nearest (X_inv,Y_inv) Point

fprintf(1,'\nNearest Points:\n\tDistance = %.5f mm\n', D_Emin)

fprintf(1,'\t\tX(%d), Y(%d) \t\t\t= %.5f mm, %.5f mm\n',K_1, K_1, X(K_1), Y(K_1))

fprintf(1,'\t\tX_inv(%d), Y_inv(%d) \t= %.5f mm , %.5f mm \n', K_2, K_2, X_inv(K_2), Y_inv(K_2))

% D evaluates the difference between actual minimum distance of nearest points

% and minimum distance of nearest points under limit condition.

% D = abs(DEmin-D_Emin);

%Eventually, Coordinates might be plotted to obtain Tooth Profile

figure(1)

plot(X(1:K_1), Y(1:K_1),'-r','LineWidth',2)

hold on

plot(-X(1:K_1), Y(1:K_1),'-r','LineWidth',2)

hold on

plot(X_inv(K2:length(X_inv)) , Y_inv(K2:length(X_inv)),'-r','LineWidth',2)

hold on

plot(-X_inv(K2:length(X_inv)) , Y_inv(K2:length(X_inv)),'-r','LineWidth',2)

hold on

plot(Qpt(1),Qpt(2),'bp', Q_invpt(1),Q_invpt(2),'gp') % Plot Closest Points

hold on

plot(-Qpt(1),Qpt(2),'bp', -Q_invpt(1),Q_invpt(2),'gp')

hold on

plot([Qpt(1); Q_invpt(1)], [Qpt(2); Q_invpt(2)], '-r','LineWidth',2) % Connect Closest Points

hold on

plot([-Qpt(1); -Q_invpt(1)], [Qpt(2); Q_invpt(2)], '-r','LineWidth',2)

hold on

base_circle = linspace(0,2*pi);

xb = rb*cos(base_circle);

yb = rb*sin(base_circle);

plot(xb,yb)

hold on

pitch_circle = linspace(0,2*pi);

xp = rp*cos(pitch_circle);

yp = rp*sin(pitch_circle);

plot(xp,yp,'--')

hold on

%tip_circle = linspace(0,2*pi);

%xt = rt*cos(tip_circle);

%yt = rt*sin(tip_circle);

%plot(xt,yt,'--m')

%hold on

root_circle = linspace(0,2*pi);

xr = rr*cos(root_circle);

yr = rr*sin(root_circle);

plot(xr,yr,'k','LineWidth',2)

XY = [(X(1)) (Y(1))]; % Point Outside Circle From Which Tangents Are Plotted

c = hypot(XY(1),XY(2));

if c <= rr

fprintf(2,'\n\tPOINT ON OR WITHIN CIRCLE RADIUS —> NO TANGENTS POSSIBLE!\n\n')

end

gap = sqrt(c^2 - rr^2); % See Wikipedia Reference

alfa = acos((rr^2 - gap^2 - c^2)/(-2*gap*c)); % See Wikipedia Reference

beta = acos((gap^2 - rr^2 - c^2)/(-2*rr*c)); % See Wikipedia Reference

alfac = [atan2(-XY(2),-XY(1)) + alfa; atan2(-XY(2),-XY(1)) - alfa]; % Angles From ‘Point’ For Tangents

xtng = XY(1) + [gap*cos(alfac(1)); gap*cos(alfac(2))]; % Tangent Point ‘x’ Coordinates

ytng = XY(2) + [gap*sin(alfac(1)); gap*sin(alfac(2))]; % Tangent Point ‘y’ Coordinates

plot(XY(1), XY(2), 'bp') % Plot ‘Point’

plot([XY(1) xtng(1)], [XY(2) ytng(1)]) % Plot Tangents

plot([XY(1) xtng(2)], [XY(2) ytng(2)]) % Plot Tangents

hold off

axis equal

title('Plot Showing Nearest Points')

line([-X_inv(end) X_inv(end)],[Y_inv(end) Y_inv(end)],'Color','r','LineWidth',2)

figure(2)

plot(X(1:K_1), Y(1:K_1),'-r','LineWidth',2)

hold on

plot(-X(1:K_1), Y(1:K_1),'-r','LineWidth',2)

hold on

plot(X_inv(K2:length(X_inv)) , Y_inv(K2:length(X_inv)),'-r','LineWidth',2) % Plot (X_inv,Y_inv) Without Overlap

hold on

plot(-X_inv(K2:length(X_inv)) , Y_inv(K2:length(X_inv)),'-r','LineWidth',2)

hold on

plot([Qpt(1); Q_invpt(1)], [Qpt(2); Q_invpt(2)], '-r','LineWidth',2) % Connect Lines

hold on

plot([-Qpt(1); -Q_invpt(1)], [Qpt(2); Q_invpt(2)], '-r','LineWidth',2)

hold on

pitch_circle = linspace(0,2*pi);

xp = rp*cos(pitch_circle);

yp = rp*sin(pitch_circle);

plot(xp,yp,'--')

hold on

base_circle = linspace(0,2*pi);

xb = rb*cos(base_circle)+0;

yb = rb*sin(base_circle)+0;

plot(xb,yb)

hold on

%tip_circle = linspace(0,2*pi);

%xt = rt*cos(tip_circle);

%yt = rt*sin(tip_circle);

%plot(xt,yt,'--m')

%hold on

root_circle = linspace(0,2*pi);

xr = rr*cos(root_circle);

yr = rr*sin(root_circle);

plot(xr,yr,'k')

hold off

axis equal

line([-X_inv(end) X_inv(end)],[Y_inv(end) Y_inv(end)],'Color','r','LineWidth',2)

xlabel('tooth thickness (mm)')

ylabel('tooth height (mm)')

title('Tooth Profile')

Star Strider
on 4 Dec 2015

The point you are plotting the tangents from cannot be on the circle radius or inside the circle. That is likely where the complex numbers are coming from. MATLAB maintains full internal precision, so the format display options will not affect that. You are not using the Symbolic Math Toolbox or symbolic variables, so vpa and related functions will have no affect on your computations.

Be absolutely certain that the point defined as my XY vector of point coordinates is outside the circle, and that c > r.

When I run my code with r=75 and XY=[0 75.00005872], it runs as it should, and does not produce complex numbers or errors. (It is difficult to see the tangent lines without enlarging the plot considerably, but they are correct.)

My code works. I have no idea what the problem is with respect to using it with your data. (I changed it so that it now works with circles not centred at the origin. I edited my previous Comment to post the new version. My code is otherwise unchanged, and the change will not affect the way it works with your data.)

Ender Rencuzogullari
on 4 Dec 2015

I will find a way to change the precision of c. I appreciate for your interest again.

Star Strider
on 4 Dec 2015

My pleasure.

The problem may be that you are changing my code to include your variables. One change that could make things easier is to create a function from my code:

function [xtng, ytng] = pt_circ_tangent(ctr, r, XY)

% PT_CIRC_TANGENT calculates and plots the tangent lines from

% a point outside the circle to points on the

% circumference. It will throw an error if the point is

% on or inside the circle.

% INPUT ARGUMENTS:

% ctr: Two-element vector with the [x, y] coordinates of

% circle center

% r: Scalar value of circle radius

% XY: Two-element vector of the [x,y] coordinates of the

% point from which the tangent lines will be drawn

% OUTPUTS:

% xtng,ytng: Points on the circle to which the tangent

% lines are plotted

a = linspace(0, 2*pi); % Assign Angle Vector

% r = 2; % Circle Radius (‘a’)

% ctr = [0.0 0.0]; % Circle Centre

x = ctr(1) + r.*cos(a); % Circle ‘x’ Vector

y = ctr(2) + r.*sin(a); % Circle ‘y’ Vector

% XY = [-5.5 3.5]; % Point Outside Circle From Which Tangents Are Plotted

c = hypot(XY(1)-ctr(1),XY(2)-ctr(2));

if c <= r

error('\n\tPOINT ON OR WITHIN CIRCLE RADIUS —> NO TANGENTS POSSIBLE!\n\n')

end

b = sqrt(c.^2 - r.^2); % See Wikipedia Reference

alfa = acos((r.^2 - b.^2 - c.^2)./(-2*b*c)); % See Wikipedia Reference

beta = acos((b.^2 - r.^2 - c.^2)./(-2*r*c)); % See Wikipedia Reference

pt_ctr_angl = atan2(-(XY(2)-ctr(2)),-(XY(1)-ctr(1))); % Angle From ‘Point’ To Circle Centre

alfac = [pt_ctr_angl + alfa; pt_ctr_angl - alfa]; % Angles From ‘Point’ For Tangents

xtng = XY(1) + [b.*cos(alfac(1)); b.*cos(alfac(2))]; % Tangent Point ‘x’ Coordinates

ytng = XY(2) + [b.*sin(alfac(1)); b.*sin(alfac(2))]; % Tangent Point ‘y’ Coordinates

figure(1)

plot(x, y) % Plot Circle

hold on

plot(XY(1), XY(2), 'bp') % Plot ‘Point’

plot([XY(1) xtng(1)], [XY(2) ytng(1)]) % Plot Tangents

plot([XY(1) xtng(2)], [XY(2) ytng(2)]) % Plot Tangents

hold off

grid

axis equal % Prevent Warping

end

Save it in your MATLAB path as: pt_circ_tangent.m

The arguments are internally comment-documented, and I commented-out the lines in the code that would otherwise over-ride the arguments. You can have as many outputs as you like. Here, I just output the tangent points on the circle. It will plot the point, circle, and tangent lines. If you don’t want that plot, just comment them out. I would not delete the plot because you can use it for reference. Consider it part of the documentation.

Ender Rencuzogullari
on 4 Dec 2015

Edited: Ender Rencuzogullari
on 4 Dec 2015

Star Strider
on 4 Dec 2015

The function works perfectly for me, for example with:

ctr = [2.5 1.5];

r = 1.6;

XY = [7.5 -2.5];

[xtng, ytng] = pt_circ_tangent(ctr, r, XY)

If you saved it in your MATLAB search path, you should have no problem using it. It will throw an error if the point is on or inside the circle. That is how I wrote it.

See if defining ‘r’ as:

r = 75 - sqrt(eps);

changes anything. The square root of the machine precision constant eps is (on my machine) 1.49011611938477e-08, so with that change, r=74.9999999850988. That should not introduce significant error into your computations, and should allow your code to work with my function.

Ender Rencuzogullari
on 5 Dec 2015

I tried to allow the program accept the function, but It did not accept. Thanks for your helps sir

Star Strider
on 5 Dec 2015

My pleasure.

I got the impression you got my code to work in your other Question. I have no idea why my function does not work on your computer. I have no problem with it.

Star Strider
on 14 Jun 2019

@Scott McCleary —

The ‘xvct’ vector is simply the independent variable of the line calculated in the ‘tngt’ assignment (dependent variable for the tangent line), and the plotted in:

plot(xvct, tngt) % Plot Tangent At Point

Dev Chhatbar
on 18 Dec 2022

### More Answers (0)

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list

How to Get Best Site Performance

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

Americas

- América Latina (Español)
- Canada (English)
- United States (English)

Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)

Asia Pacific

- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)