Need procedure for equation of circle defined by 2 pts and tangent line - edit 1 lazarus / 21-General ---------------------------------------------------------------------- dculp · 2021-02-01 12:32 Given --    1) the coordinates of 2 points on a circle (X1,Y1) and (X2,Y2)    2) a line that is tangent to the circle -- y = mx + b where m is the slope and b is the y-intercept. (The point of tangency isn't known and generally wouldn't be one of the above two points on the circle.) Find -- the center of the circle (X0,Y0) Note that the radius of the circle isn't known in advance. The problem is shown here (https://www.emathzone.com/tutorials/geometry/equation-of-a-circle- given-two-points-and-tangent-line.html). The solution requires solving a set of nonlinear simultaneous equations. I might be able to do this but the math is tedious and would be error prone. Therefore, I'm looking for a pre-packaged procedure for this. Thanks for any suggestions, Don C. Edit #1 -- Designate the circle center as (X0,Y0). Designate the tangency point as (X3,Y3). The circle radius will be R. These 5 parameters are initially unknown. Equations to be solved -- 1) Y3 = m*X3 + b // equation of tangent line evaluated at (X3,Y3) 2) R^2 = (X1 - X0)^2 + (Y1 - Y0)^2 // square of dist from (X1,Y1) to (X0,Y0) 3) R^2 = (X2 - X0)^2 + (Y2 - Y0)^2 // square of dist from (X2,Y2) to (X0,Y0) 4) R^2 = (X3 - X0)^2 + (Y3 - Y0)^2 // square of dist from (X3,Y3) to (X0,Y0) 5) Y0 + (1/m)*X0 = Y3 + (1/m)*X3 // requires some manipulation to achieve From the above there are 5 equations in 5 unknowns -- theoretically solvable. However, some of the equations involve squared terms which makes the solution difficult. Simple (easy) example -- (X1,Y1) = (-2,1) (X2,Y2) = (+2,1) m = 0 // horizontal tangent line b = 0 //  tangent line intersects the Y axis at Y=0 From the last 2 criteria the tangent line must be coincident with the X axis. The first 2 criteria are symmetric about the Y axis so that the circle center must lie on the Y axis. The result of these conditions is that the tangent point must lie on the intersection of the X and Y axes -- i.e., (X3,Y3) = (0,0). The original problem now reduces to one with 3 known points on the circle. The results are -- R = 2.5 (X0,Y0) = (0,2.5) See -- https://www.mathportal.org/calculators/analytic-geometry/circle- through-three-points.php http://www.ambrsoft.com/TrigoCalc/Circle3D.htm The above example was easy because m = 0 and b = 0. The problem is significantly more difficult if other conditions for the tangent line are used; hence, my original request. ---------------------------------------------------------------------- howardpc · 2021-02-01 15:29 Untested, but a bit of high school algebra would give you this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  Math; function X0Y0AreValid(x1, x2, y1, y2, m, b: Single; out x0, y0: Single): Boolean;var  denom: Single;begin  denom := 2 * (x2 - x1 + m * (y2 - y1);   Result := Abs(denom) > 0.0000001;  case Result of    True: begin            x0 :=(Sqr(x2) - Sqr(x1) + Sqr(y2) - Sqr(y1) - b) / denom;            y0 := m * x0 + b;          end;    False: begin             x0 := NaN;             y0 := NaN;           end;  end;end; ---------------------------------------------------------------------- dculp · 2021-02-02 03:03 howardpc -- Your code requires a ")" in the denom statement. I assume that this should go after x1. With m = 0 and b = 0 and with (x1,y1) = (-2,1) and (x2,y2) = (+2,1), your result is (x0,x0) = (0,0). The result should be (x0,y0) = (0,2.5) -- see the example in the edit of my original post. Note that your equation for y0 is a line through the center of the circle, not a line that is tangent to the circle. This can only be corrected if the tangent point (x3,y3) can be determined. ---------------------------------------------------------------------- howardpc · 2021-02-02 10:25 I merely provided you with a back-of-envelope response that took me no more than 10 minutes, and as I said is completely untested. It was not offered as a reliable solution. I have no use case for this scenario, so have no motivation to write tests or demonstrations of its use which would be needed to provide an acceptable solution. I hope I have prompted you to work out your own solution, and write tests that verify what you come up with. You have the nous to critique what I offered, so you clearly have the ability to meet your own need with a little effort. ---------------------------------------------------------------------- dculp · 2021-02-02 11:17 howardpc -- Perhaps there is a simpler method than the one that I suggested in my edit. Otherwise, solving a system of 5 simultaneous *nonlinear* equations isn't something that may be resolved "with a little effort". I have searched rather extensively online. The closest solution that I have found is here (https://www.emathzone.com/tutorials/geometry/equation-of-a-circle- given-two-points-and-tangent-line.html). However, the author leaves the final (difficult) part of the solution to the reader. That's why I have turned to this forum for help. I would still appreciate any suggestions for this problem. ---------------------------------------------------------------------- Bart · 2021-02-02 11:55 Mathematics is really long time ago, but: The line that goes through the midpoint of the linesegment (x1,y1) (x2,y2) and that runs perpendicular to that line segment, also goes throug the midpoint of the circle. The equation for that line is a first degree polynomial. Using this info might perhaps give you a slightly less complicated set of equations to solve? (Untested theory.) Bart ---------------------------------------------------------------------- Bart · 2021-02-02 12:26 Probably not quite that easy as you suggest. [Edit]In reply to a post by Thaddy, which he later removed.[/edit] Another thing. I would simplify the problem by assuming the origin (midpoint) of the circle is at (x=0,y=0). Makes calculations (and equations simpler). Since this is a simple translation (is that the correct mathematical term?), it is simple to adjust the coördinates of the given 2 points and the equation for the tangent line, and after finding the solution, just translate back. (You would in this case want to calculate the radious of course.) (i.o.w: generalize the solution for the simple case (Origin=(0,0)) to the general case (Origin=(A,B))) Bart ---------------------------------------------------------------------- dculp · 2021-02-02 12:43 Bart -- Unless I am misunderstanding, your analysis (reply #5) isn't correct. The line that connects (X1,Y1) and (X2,Y2) is a chord of the circle. From the midpoint of this chord, the *perpendicular* to this chord will pass through the center of the circle. The slope of this perpendicular line (or the perpendicular to this perpendicular line which is the slope of the chord line) generally won't be the same as the slope m of the tangent line. (Note that the tangent line may be placed anywhere on the circumference of the circle, depending on m and b. On the other hand, the chord line is exactly defined by the choice of (X1,Y1) and (X2,Y2) for which the slope of the chord line is fixed -- call this m'. m' will only equal m under unusual circumstances. ) Please let me know if my thinking is wrong. ---------------------------------------------------------------------- Thaddy · 2021-02-02 12:43 Sorry bart, I deleted my entry to solve it properly. Otherwise people get confused. The above answer is like what I wrote before: finding the point at the circle. ---------------------------------------------------------------------- balazsszekely · 2021-02-02 17:56 There is no way you can solve that system of equations analytically.  If you know the values of x1, y1, x2, y2, m, n you can attempt a numerical solution: 1. Paste the link from the attached txt into a browser(too long to paste it here) 2. Resize the memo below "Equation(s)" 3. Enter the values for a, b, c, d, m, n then press "Solve" PS: I wouldn't even attempt to write a program that is able to solve the system of equations numerically. It's far from trivial. ---------------------------------------------------------------------- Bart · 2021-02-02 19:12 Quote from: dculp on February 02, 2021, 01:43:08 pmBart -- Unless I am misunderstanding, your analysis (reply #5) isn't correct. The line that connects (X1,Y1) and (X2,Y2) is a chord of the circle. From the midpoint of this chord, the *perpendicular* to this chord will pass through the center of the circle. The slope of this perpendicular line (or the perpendicular to this perpendicular line which is the slope of the chord line) generally won't be the same as the slope m of the tangent line. I reralized this 2 seconds after I wrote it and then quickly edited my post. Seems like you read it before I corrected it. Quote from: dculp on February 02, 2021, 01:43:08 pmPlease let me know if my thinking is wrong. You're absolutely correct. I used to love maths in highschool (I was rather good at it), but since I never ever have to use it in my day job, decline of knowledgde has set in (rot might be a better word)  Bart ---------------------------------------------------------------------- Peter H · 2021-02-02 19:27 I tried it, but my higher level mathematics training is 45 years ago. This said, the modern way to solve equations are Computer Algebra Systems. In Wolfram Alpha you can write e.g. "solve x^2 + y^2=r^2=x*m for r" https://www.wolframalpha.com/input/?i=solve+x%5E2+%2B+y%5E2%3Dr%5E2%3D x*m+for+r Or:  solve x^2 + y^2=r^2=x*m+c for x,r https://www.wolframalpha.com/input/?i=solve+x%5E2+%2B+y%5E2%3Dr%5E2%3D x*m%2Bc+for+x%2Cr (I do not know the complete syntax, learned it from examples and trial and error) So you should express your problem in the mathematically most simple -but precise and complete- way and let a Computer Algebra System solve it. The most simple form of a circle equation is e.g. "(x-c_x)^2+(y-c_y)^2 = r^2" , where "c_x" and "c_y" are the center coordinates. This needs a lot of typing and I dont know, if the website accepts long expressions pasted from an editor but there are free CAS systems that you can install and use or purchase wolfram alpha, but probably the latter is overkill for such geometric problems. You will probably need the formula for the circle and the formula for the orthogonal shortest distance between a point and a line, which is equal to r in this case. ---------------------------------------------------------------------- dculp · 2021-02-02 22:58 GetMem & Peter H -- I appreciate your suggestions. However, I need to incorporate the general solution into a Pascal program so I need the Pascal code (or other code that I can convert to Pascal). An iterative solution is possible but not the most desirable -- 1. Start with a very large radius R. 2. Using R, find a circle with center (X0,Y0) that includes points (X1,Y1) and (X2,Y2). Because R is very large and if the direction of curvature is correctly chosen, the line will be outside the circle. 3. Calculate the minimum distance L from the line to (X0,Y0). 4. Compare L and R. Initially, L > R since the line is outside the circle. 5. Slowly decrease R (deflate the circle) so that it bulges toward the line through the gap (X1,Y1) <--> (X2,Y2). 6. Repeat steps 3, 4, 5 until L = R (the circle just touches the line). Then R is known and all other variables can be calculated. If the circle's initial direction of curvature is "incorrect" (opposite to above) then the line will intersect the initial large circle at 2 points (forming a chord). Then initially L < R since the line is inside the circle. Then slowly decrease R until L = R (the line touches the circle only at one point -- the point of tangency). The above should always give a solution. However, it requires a good search algorithm (one that converges but not too many iterations) which is a separate project. ---------------------------------------------------------------------- Peter H · 2021-02-02 23:27 Given the points and the line, the  problem has only one and only one (not more and not less) solutions, so you should get one formula as a result that is easily written in pascal. (Unless the two points of the circle are on the line which should be tested before) In the case of Wolfram Alpha you can also get complex solutions (which contain sqrt(-xyz)), which can be ignored. Or better said, you should get one formula for r one for c_x and one for c_y which is the center of the circle and possibly need r as an argument. Edit: I rethought it. You can always draw two circles that fulfil the condition. If one is small, the other is very large in most cases. The problem has always two solutions (which cannot be identic) so r should be given as the roots of a quadratic equation. The problem can be drawn by circle and ruler, so there can be only rational solutions (which can be calculated without iteration or trigonometry) and always two real number solutions (which can be  infinite) Because quadratic equations have two roots only and always, there are no complex roots and solutions if all coordinates and coefficients are real. What if the two dots are parallel to the line? You should get one small circle, and, because parallel lines hit in infinite distance, one circle with infinite radius. So the results for r, c_x and c_y should be reziprok to the solutions for a quadratic equation. Therefore a CAS system can calculate solution formulas without iteration, but I am too tired to do it. ---------------------------------------------------------------------- Peter H · 2021-02-03 03:31 I tried it with Wolframalpha, but I am not happy with the result: Computing time exceeded. https://www.wolframalpha.com/input/?i=solve+r%5E2+%3D+%28x- c_1%29%5E2%2B%28y- c_2%29%5E2+%3D+%28a*c_1+%2Bb*c_2+%2Bc%29%5E2%2F%28a%5E2%2Bb%5E2%29+for +r%2C+c_1%2C+c_2 I am sure there is a (relatively) simple solution. Note the line equation is here given in the form ax + by + c = 0 c_1 means c_x and c_2 means c_y, because WA does not accept c_x and c_y as names. ---------------------------------------------------------------------- avk · 2021-02-03 04:27 It seems that the original problem can always be reduced to a problem with three known points on a circle, provided that the points on the circle do not coincide and none of them belongs to the tangent, if we recall a theorem from school planimetry. ---------------------------------------------------------------------- 440bx · 2021-02-03 06:14 Quote from: dculp on February 01, 2021, 01:32:31 pmGiven --    1) the coordinates of 2 points on a circle (X1,Y1) and (X2,Y2)    2) a line that is tangent to the circle -- y = mx + b where m is the slope and b is the y-intercept. (The point of tangency isn't known and generally wouldn't be one of the above two points on the circle.) Find -- the center of the circle (X0,Y0) The center of the circle is at the intersection of the perpendicular to the chord's midpoint and the perpendicular to the tangent. The equation of the chord is easy to calculate since the two points are given.  The infinite set of circles defined by those two points all have their center on the line that is the perpendicular at their midpoint (and _not_ on the chord's line.)  This is easy to calculate since the chord's two points are given and its midpoint is just a calculation away too. The equation of the tangent is given.  The equation of its perpendicular is the same equation but with the negative reciprocal of the slope.  The center of the circle must also reside on that perpendicular. Since the circle's center must be on both of those perpendiculars, determine their intersection by equating the "y"s and solve the resulting equation for x.  Known "x" replace it in either perpendicular equation to obtain "y". Attached is a picture showing the points and lines involved along with a Geogebra "program" that allows the user to move the chord's and tangent's point. The one thing the program should do is ensure that the equation of the tangent isn't the same as the equation of the chord since, in that case, there is no circle, i.e, no solution. HTH. ---------------------------------------------------------------------- Bart · 2021-02-03 12:27 Quote from: Peter H on February 03, 2021, 12:27:26 amWhat if the two dots are parallel to the line? You should get one small circle, and, because parallel lines hit in infinite distance, one circle with infinite radius. That makes no sense to me. If the circel with infinite radius passes through the 2 given points, the given line (which does NOT pass through those 2 points), will never be tangent to that circle. Bart ---------------------------------------------------------------------- Bart · 2021-02-03 12:58 According to this page it is possible to calculate where the tangent point is (if the tangent line and the line segment connecting the 2 points are not parallel). You can calculate the intersection (X) of the tangent line and the line connecting the 2 points (P1 and P2). You can then calculate the length of P1-X, P2-X and therefore the length of X-tangent point. Say the length X-Tangent point = t Then t^2 = Length(P1-X)*Length(P2-X). Once you have that length, you can calculate the coördinates of the tangent point. The midpoint can then be found by construction 2 lines: - one perpendicular to P1-P2, goingt through the midpoint of P1P2 - one perpendicular to the given tangent line, going through the tangent point. The center of the circle is at the intersection of these 2 lines. Bart ---------------------------------------------------------------------- dculp · 2021-02-03 14:19 Quote from: Bart on February 03, 2021, 01:58:12 pmAccording to this page ... Bart Bart -- There are a number of questions on this page. I'm not sure which one you mean. Can you quote the particular question to which you refer? ---------------------------------------------------------------------- dculp · 2021-02-03 14:44 Quote from: 440bx on February 03, 2021, 07:14:11 amQuote from: dculp on February 01, 2021, 01:32:31 pmGiven --    1) the coordinates of 2 points on a circle (X1,Y1) and (X2,Y2)    2) a line that is tangent to the circle -- y = mx + b where m is the slope and b is the y-intercept. (The point of tangency isn't known and generally wouldn't be one of the above two points on the circle.) Find -- the center of the circle (X0,Y0) The center of the circle is at the intersection of the perpendicular to the chord's midpoint and the perpendicular to the tangent. The equation of the tangent is given.  The equation of its perpendicular is the same equation but with the negative reciprocal of the slope.  The center of the circle must also reside on that perpendicular. Change the tangent line notation slightly -- y = mx + b1 The equation for the line that is perpendicular to the tangent line will be y = (-1/m)x + b2 b2 is not known (b2 <> b1). Is there a way to find b2 (7.94 in your picture)? Otherwise, the line that is perpendicular to the tangent line is indeterminate. Note -- The circle diameter is not known (must be determined such that the circle is tangent to the line) so maybe this is the problem. I think that using the line that is perpendicular to the chord's midpoint may be helpful. ---------------------------------------------------------------------- Bart · 2021-02-03 15:44 Quote from: dculp on February 03, 2021, 03:19:21 pmThere are a number of questions on this page. I'm not sure which one you mean. Can you quote the particular question to which you refer? It's the part that starts with: QuotePhilip Lloyd , Specialist Calculus Teacher, Motivator and Baroque Trumpet Soloist. Updated 2 years ago · Author has 3.4K answers and 13.2M answer views How do you construct a circle passing through 2 points outside line L and tangent to line L? Bart ---------------------------------------------------------------------- Bart · 2021-02-03 15:52 Quote from: dculp on February 03, 2021, 03:44:10 pmb2 is not known (b2 <> b1). Is there a way to find b2 (7.94 in your picture)? What 7.94? You can calculate the intersection point of the tangent line and the line through P1P2 You can calculate the length of the line segment IntersectionPoint- TangentPoint. (Which is what that page explains.) Since that point is on the tangent line, you can now calculate the exact coördinate of that point. So, now you know: P1, P2, the tangent point, the midpoint of P1P2. That gives you 2 lines, a new intersection point (the center of the circle (origin O)). The radius is of course then the dsitance between O and either P1, P2 or the tangent point/tangent line. All these equations should be first degree polynomials, so the set of equations should be easier to solve? Bart ---------------------------------------------------------------------- winni · 2021-02-03 16:19 Hi! Yes, Bart! Or the other way round: Get the center of P1P2 = M12. Get the slope of P1P2. Take a perpendicular line trough M12 with the slope of P1P2 + 90°. This is the line were the circle center must be. All points are know so the equation of the line is know. Take the second line with the known parameters y = mx + b The crossing point of the two lines is not such a miracle. This is P3, the tangential point for the circle. Now you can (see above) draw the line P1P3, take the midpoint and draw a perpendicular line through M13=  Center of P1P3. Take this line and  take the perpendicular line through M12. WHere those two lines cross lays the center of the circle. Computing the radius now should not be a big problem. Winni ---------------------------------------------------------------------- Blaazen · 2021-02-03 16:27 @ 440bx Very nice. Isn't there a term "secant" for the line? ---------------------------------------------------------------------- Peter H · 2021-02-03 17:59 My Wolfram Alpha example above was wrong. Also I found an error on the website, https://www.emathzone.com/tutorials/geometry/equation-of-a-circle- given-two-points-and-tangent-line.html where the OP pointed to. Equation (v) has an error, not (x1,y1) must be referred, but h,k I have now written the second alternative for solution as described on this website. Wolfram Alpha now calculates h, but does not simplify it and doesnt calculate k. (Standard computing time exceeded) Edit: k is also calculated, a closer look to the result is required, it is in the middle deeply buried. I tried also the free CAS system Yacas, but this doesnt try and gives no error. Anyway here is it, if somebody has a capable CAS program, possibly he could give the solutions for h and k, r is then easily calculated from this. This is the formula, it can be seen prettyprinted on the Wolfram Alpha website and in the attachement Nomenklature: (x1,y1), (x2,y2): The two dots. (h,k) : The center of the circle. a,b,c: The coefficients of the line defined by the formula ax+by+c=0 solve ( (x_1-h)^2+(y_1-k)^2=(x_2-h)^2+(y_2-k)^2= (a*h +b*k +c)^2/(a^2+b^2)) for h,k https://www.wolframalpha.com/input/?i=solve+%28+%28x_1- h%29%5E2%2B%28y_1-k%29%5E2%3D%28x_2-h%29%5E2%2B%28y_2- k%29%5E2%3D+%28a*h+%2Bb*k+%2Bc%29%5E2%2F%28a%5E2%2Bb%5E2%29%29+for+h%2 Ck It is not a pascal problem, but interesting.  BTW, Wolfram Alpha displays two results for h and k, (where each of the results have a +- result, this means there are four results) because it also calculates results for complex coefficients. ---------------------------------------------------------------------- Peter H · 2021-02-03 19:29 Quote from: Bart on February 03, 2021, 01:27:15 pmQuote from: Peter H on February 03, 2021, 12:27:26 amWhat if the two dots are parallel to the line? You should get one small circle, and, because parallel lines hit in infinite distance, one circle with infinite radius. That makes no sense to me. If the circel with infinite radius passes through the 2 given points, the given line (which does NOT pass through those 2 points), will never be tangent to that circle. Bart This is a discussion going back to the ancient greek. It is solved (respectively well defined) in mathematics and geometry today, but I only know the solution and cannot explain or discuss it deeply  You must assume, "infinity" is a land of mystery. It maybe, this universe is circular and finite and "infinite" does not exist. If this is true even irrational and transcendent numbers do not exist, because these have infinite length but nobody knows. Rational numbers do exist, because these are periodic and therefore circular. ---------------------------------------------------------------------- dculp · 2021-02-03 19:30 Quote from: Bart on February 03, 2021, 04:52:25 pmQuote from: dculp on February 03, 2021, 03:44:10 pmb2 is not known (b2 <> b1). Is there a way to find b2 (7.94 in your picture)? What 7.94? You can calculate the intersection point of the tangent line and the line through P1P2 You can calculate the length of the line segment IntersectionPoint- TangentPoint. (Which is what that page explains.) Since that point is on the tangent line, you can now calculate the exact coördinate of that point. So, now you know: P1, P2, the tangent point, the midpoint of P1P2. That gives you 2 lines, a new intersection point (the center of the circle (origin O)). The radius is of course then the dsitance between O and either P1, P2 or the tangent point/tangent line. All these equations should be first degree polynomials, so the set of equations should be easier to solve? Bart 7.94 is from the picture Circle2pointsAndTangent.png posted by 440bx (see the left panel of the picture -- "EquationTangentPerpendicular: y = -0.58x + 7.94" in red). This approach looks good. I'll try coding it. ---------------------------------------------------------------------- 440bx · 2021-02-04 22:48 Quote from: Blaazen on February 03, 2021, 05:27:23 pm@ 440bx Very nice. Isn't there a term "secant" for the line? Thank you.  Yes, the line that creates the chord is a secant and the segment of that line inside and part of the circle is the chord. Quote from: dculp on February 03, 2021, 03:44:10 pmThe equation for the line that is perpendicular to the tangent line will be y = (-1/m)x + b2 b2 is not known (b2 <> b1). You're right.  The fact that b2 is unknown totally dropped out of my mind.  My mistake. Quote from: dculp on February 03, 2021, 03:44:10 pm Is there a way to find b2 (7.94 in your picture)? There is no simple way of determining the value of b2 (there is no equation that will yield the value directly.) Quote from: dculp on February 03, 2021, 03:44:10 pmNote -- The circle diameter is not known (must be determined such that the circle is tangent to the line) so maybe this is the problem. That part I understood.  The tangent is what restricts the circle to have one and only one possible radius. Quote from: dculp on February 03, 2021, 03:44:10 pmI think that using the line that is perpendicular to the chord's midpoint may be helpful. Most definitely helpful because the circle's center resides somewhere (to be determined) on that line.  I coded a quick and a bit dirty solution.  The solution as presented isn't general but, the method used is.  There are a number of checks and optimizations missing but, I hope their absence makes the code easier to understand.  The code solves the problem shown in ChordAndTangentLineA.   ChordAndTangentLineB is there to show that the slope of the perpendicular to the chord should be used to choose whether to converge to the solution using x or y displacements.  In the case of "A" a "y" displacement gives the fastest convergence, in the case of "B", an x displacement converges faster.  If the perpendicular's slope is 1 then x or y displacements will converge at the same speed. Now referring to the ChordAndTangentLineA, the first center to be considered should be at the midpoint between ChordA and ChordB because that produces the smallest possible circle.  It is using that circle that the code should ensure that the equation of the tangent is actually a tangent, that is, it does _not_ touch/intersect the circle at more than one point (if any at all).  The code to do that has been omitted for clarity's sake but, production quality code should do that and, a few other things mentioned in the code comments that are also missing (all fairly easy and simple.) Looking at ChordAndTangentLineA, as the CircleCenter slides down the perpendicular, the radius increases and the "TargetTangentPoint" gets closer to the "TangentPointRestrictsRadius".  The gist is to keep sliding the circle's center down the perpendicular until the distance between those two points is zero (or considered zero for practical purposes.)   When the distance is zero then the radius, the circle's center and the point of tangency are all known. The convergence is done by sliding the "guess" center down by half the distance between those two points until the distance is, for practical purposes, zero. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$APPTYPE      CONSOLE} {$LONGSTRINGS    OFF}{$WRITEABLECONST ON}{$DESCRIPTION  'Chord and Tangent proof of concept'} {$DEFINE TRACK_CONVERGENCE} program _ChordAndTangentProofOfConcept;  { NOTE: there are a number of important sanity checks which are omitted,    }  {       among them division by zero, ensuring the tangent line is outside   }  {       the smallest possible circle determined by the chord points, which  }  {       coordinate, x or y, to vary to maximize convergence speed and others}  {       left as an exercise to the reader.                                  }  uses  Sysutils; type  TPointEx = record    x, y       : extended;  end;   Tmx      = record        { line equation in the form y = mx + b           }    m, b     : extended  end; { ------------------------------------------------- -------------------------- } function Distance({$IFDEF FPC } constref {$ELSE} var {$ENDIF}                  PtA, PtB : TPointEx) : extended;  { calculates and returns the distance between two points                  }begin  result := sqrt(sqr(PtB.x - PtA.x) + sqr(PtB.y - PtA.y));end; { ----------------------------------------------------- ---------------------- } var  { chord points, line and perpendicular related variables                    }   ChordA          : TPointEx = (x :  0; y : 10);  ChordB          : TPointEx = (x : 30; y : 20);   ChordMid        : TPointEx = (x :  0; y :  0);  { mid point - tbd         }   ChordLine { y } : Tmx      = (m : 0; b : 0);    { tbd                     }  ChordPerp { y } : Tmx      = (m : 0; b : 0);    { tangent points, line and perpendicular related variables                }   TangentA        : TPointEx = (x : -20; y : -50);  TangentB      : TPointEx = (x :  70; y : -40);   TangentLine     : Tmx      = (m : 0; b : 0);    { tbd                       }   PerpTangentLine : Tmx    = (m : 0; b : 0);    { tbd                       }  PerpIntersectPt : TPointEx = (x : 0; y : 0);    { tbd                       }   { circle center                                                           }   CircleCenter    : TPointEx = (x : 0; y : 0);    { tbd                     }   { values to be determined - all done when Radius = DistanceToTangent within }  { the Tolerance constant below.                                           }   Radius            : extended = 0;  DistanceToTangent : extended = 0;    { DistanceCenterToPointOnTangentLine   }   AdjustmentY       : extended = 0;    { adjustment from current guess to next}   Buf               : packed array[0..511] of char; const  Tolerance : extended = 0.00001; begin  with ChordLine do  { could make this a function/procedure                   }  begin    m := (ChordB.y - ChordA.y) / (ChordB.x - ChordA.x);          { slope      }     { use ChordA point to calculate b.  b := y - mx                           }     b := ChordA.y - (m * ChordA.x);     { s/b 10 if ChordA.x = 0            }  end;   { same as above for the tangent to the circle                             }   with TangentLine do  begin    m := (TangentB.y - TangentA.y) / (TangentB.x - TangentA.x);  { slope      }     { use the TangentA point to calculate b.  b := y - mx                   }     b := TangentA.y - (m * TangentA.x);  end;   { calculate the equation of the perpendicular to the tangent line. The b    }  { value is recalculated for every "movement" of the CircleCenter.           }   PerpTangentLine.m := - 1 / TangentLine.m;   { calculate the mid point between ChordA and ChordB                       }   ChordMid.x := (ChordB.x + ChordA.x) / 2;  ChordMid.y := (ChordB.y + ChordA.y) / 2;   { calculate the equation of the perpendicular at the midpoint of the cord,  }  { first the slope m                                                         }   ChordPerp.m := - 1 / ChordLine.m;   { calculate b using the midpoint                                          }   ChordPerp.b := ChordMid.y - (ChordPerp.m * ChordMid.x);   { determine the center of the circle using a starting "guess" and refine it }  { in each successive iteration.  The starting guess is the chord's midpoint }  { because that point yields the smallest possible circle.                   }   { NOTE : it is here where a "production quality" algorithm would ensure     }  {        the tangent line is actually a tangent and not a secant.           }   CircleCenter := ChordMid;  Radius       := Distance(ChordA, CircleCenter);   while true do  begin    { now we need to calculate the distance between the CircleCenter and the  }    { tangent line.  First calculate the b value of the perpendicular using   }    { the value of CircleCenter (CircleCenter must be on it.)                 }     PerpTangentLine.b := CircleCenter.y - (PerpTangentLine.m * CircleCenter.x);     { calculate the intersection point of the tangent and its perpendicular   }     with PerpTangentLine do    begin      PerpIntersectPt.x := (- PerpTangentLine.b + TangentLine.b)                         / (  PerpTangentLine.m - TangentLine.m);      with PerpTangentLine do    begin        PerpIntersectPt.y := m * PerpIntersectPt.x + b;      end;    end;     { now that we have two points calculate the distance between them         }     DistanceToTangent := Distance(CircleCenter, PerpIntersectPt);     {$IFDEF TRACK_CONVERGENCE}      StrFmt(Buf, 'Center              : (x : %g, y : %g)', [CircleCenter.x,                                                           CircleCenter.y]);    writeln(Buf);       StrFmt(Buf, 'Distance to tangent : %g', [DistanceToTangent]);      writeln(Buf);    {$ENDIF}     { if the distance to the tangent is less than the tolerance then we have  }    { a reasonably good approximation.                                      }     if abs(Radius - DistanceToTangent) < Tolerance then break;   { we need to take another guess that will lower the distance to the     }    { tangent.   Make the next guess equal to the current CircleCenter plus   }    { half the distance between the lowest point on the circle and the        }    { current intersection to the tangent line in the Y direction.            }     AdjustmentY    := - (DistanceToTangent - Radius) / 2;      {$IFDEF TRACK_CONVERGENCE}    StrFmt(Buf, 'Adjustment          : %g', [AdjustmentY]);      writeln(Buf);    {$ENDIF}     CircleCenter.y := CircleCenter.y + AdjustmentY;     CircleCenter.x := (CircleCenter.y - ChordPerp.b)                  /  ChordPerp.m;     {$IFDEF TRACK_CONVERGENCE}      StrFmt(Buf, 'Center              : (x : %g, y : %g)', [CircleCenter.x,                                                           CircleCenter.y]);    {$ENDIF}     { calculate the new radius                                              }     Radius := Distance(ChordA, CircleCenter);     {$IFDEF TRACK_CONVERGENCE}  { originally missing the conditional if       }      writeln(Buf);      writeln; writeln;    {$ENDIF}                    { and endif                                 }  end;   {$IFDEF TRACK_CONVERGENCE}    writeln;  {$ENDIF}   writeln;  writeln('results : ');   StrFmt(Buf, '  Circle center at (%g, %g)', [CircleCenter.x, CircleCenter.y]);  writeln(Buf);  StrFmt(Buf, '  Circle radius is %g', [Radius]);  writeln(Buf);   writeln;  writeln('Press enter/return to end this program');  readln;end. If the comments in the code leave something unclear, just ask. Attached is the Geogebra script to "play" with the case shown in the "A" picture. HTH. ETA: Added a missing conditional compile for writeln(s) at the end of the while loop (see code).  (doesn't affect the results, only the output when not tracking convergence. ---------------------------------------------------------------------- speter · 2021-02-05 06:18 I'm not sure why we are doing a geometry problem on a programming forum... ;-) Given 2 points on a circle (p1, p2) and 2 points that define a tangent (p3, p4):  + calculate the line equations for each line  + calculate the intersection of the 2 lines (p5)  + if the intersection point is inside the line p1-p2, it is invalid  + calculate the distances: (d1): p1->p2; (d2): p2->p5  + calculate the distance (d3): p5->p6 [p6 = the point on the tangent line nearest the circle's centre]  + d3 = sqrt(d2 + (d1+d1)); using "Intersecting Secant-Tangent Theorem" https://www.varsitytutors.com/hotmath/hotmath_help/topics/int ersecting-secant-tangent-theorem  + you already know the line equation for the tangent line (p3-p4), which passes through p5 and p6  + use Pythagoras' theorum to calculate p6 (given p5 and d3)  + once you have p6, you have 3 points on the circle circumference, so you can calculate the centre and radius ---------------------------------------------------------------------- Paolo · 2021-02-05 11:42 in general you can have two circle matching the constraint (see picture below my implementation results), no tested in details. to solve the problem two circle equation for the two points (X1, Y1) and (X2, Y2) (the unknown are 3 that are a,b, c) X1^2+Y1^2+ax1+by1+c=0 X2^2+Y2^2+ax1+by2+c=0 by the above espress b=f1(a) and c =f2(a) then solve the sistem X^2+Y^2+ax+f1(a)y+f2(a)=0 y=mX+q and put the "delta" = 0 you have an equation with second degree polinom in "a", solve that for both the sign in front of the sqrt and then recover b and c finally X0=-a/2, Y0=-b/2 ---------------------------------------------------------------------- Peter H · 2021-02-05 19:44 Rotate and translate the coordinate system, so that the line falls together with the (new) x-axis and the intersection of the line and the old x-axis is the new zeropoint. Then the line and the parameters b and c are zero and a=1 and the y coordinate of the third point is known and zero. Then translate and rotate the result back. For this simplifyed problem Wolfram Alpha calculates a much shorter result that is simplifyed. Nomenklature: (x1,y1), (x2,y2): The two dots. (h,k) : The center of the circle. a,b,c: The coefficients of the line defined by the formula ax+by+c=0 https://www.wolframalpha.com/input/?i=solve+%28+a%3D0%2Cb%3D1%2Cc%3D0% 2C+%28x_1-h%29%5E2%2B%28y_1-k%29%5E2%3D%28x_2-h%29%5E2%2B%28y_2- k%29%5E2%3D+%28a*h+%2Bb*k+%2Bc%29%5E2%2F%28a%5E2%2Bb%5E2%29%29+for+h%2 Ck Problem solved!  Edit: There is still something to fix, with a,b,c, but this is my route to the solution.  Edit2: Because in this special case r^2 =k^2 and all three bracketed terms are equal to r^2, a=0,b=1,c=0 ist my final solution. The only thing you need additionally are functions for coordinate transformation, forward and backwards. Edit3: This solution with coordinate transformation is probably faster to calculate than the generic case, because the formulas are shorter and simpler. It is possible to simplify and optimize the solutions further, if you type them into a free CAS application, e.g. YACAS or MAXIMA. The resulting Code can be pasted into the sourcecode. (Wolfram Alpha free online version doesnt support long line inputs, and doesnt output "*" operators, this has some problems) ---------------------------------------------------------------------- Paolo · 2021-02-05 20:36 The step I showed are the canonical way of solving these problems, I tested it and it found 1 or 2 solutions depending on the input (even in the case one of two point is touched by the tangent), it requires simple computation (solution of 2 degree polinomial that is in closed form ), only boring computation involved, (not sure but no easy closed form esist). ---------------------------------------------------------------------- 440bx · 2021-02-05 21:17 Just a thought... It would be very nice if those who claim to have a solution would include the computations to the supposed solution, that would give the "explanation" some credibility. To contribute to that, use the following: Chord intersection points : A = (0, 10) and B = (30, 20) Points belonging to the tangent : T1 = (-20, -50) and T2 = (70, -40) (used to derive the equation of the tangent line.) to verify the solution, use the program I previously posted. Thank you. ---------------------------------------------------------------------- Paolo · 2021-02-05 21:56 Right, but I wrote the code in delphi, just the time to rewrite the code in Lazarus and I'll post the code. Please note that I already provided the math algorithm in the previous post. I wrote the code today, not sure all is fine, I'll check the test case are you proposing. ---------------------------------------------------------------------- speter · 2021-02-06 05:32 Quote from: 440bx on February 05, 2021, 10:17:41 pmIt would be very nice if those who claim to have a solution would include the computations If anyone is interested, I have attached a project ZIP (and screenshot). The program allows the user to enter 4 points using the mouse and displays the results. cheers S. ---------------------------------------------------------------------- 440bx · 2021-02-06 08:03 Quote from: speter on February 06, 2021, 06:32:11 amIf anyone is interested, I have attached a project ZIP (and screenshot). The program allows the user to enter 4 points using the mouse and displays the results. Thank you for posting the code.  Your code works with the points you selected but, unfortunately, it does _not_ work with the test points I suggested.  With the points I suggested, your program says the circle center is at (26.4, -19.2) which is not correct, the center is at (24.06, -12.18).  It says the radius is 39.4 but the correct value is 32.72.   (all values verified using Geogebra) Just for the record, the code I posted previously gives correct results for the default values you set in the program (results also verified with Geogebra.) HTH. ---------------------------------------------------------------------- Paolo · 2021-02-06 08:21 @440bx it seems in line with my results, still found 2 circles ---------------------------------------------------------------------- Paolo · 2021-02-06 08:23 the other circle ---------------------------------------------------------------------- 440bx · 2021-02-06 08:37 Quote from: Paolo on February 06, 2021, 09:21:12 am@440bx it seems in line with my results, still found 2 circles But the values your program shows are _not_ the ones in the graph you just posted (see the screenshot I posted of your program results.)  In addition to that, your program didn't produce the graph correctly (I didn't include that part in the screenshot.) Did you modify your program and forgot to post the new version ? ---------------------------------------------------------------------- Paolo · 2021-02-06 08:50 Hello 440bx in the first plot th centre of circle is as per your resutls (24.06, -12.18) even if in the plot not rounded to 2nd decimal. ---------------------------------------------------------------------- speter · 2021-02-06 09:03 Quote from: 440bx on February 06, 2021, 09:03:06 amQuote from: speter on February 06, 2021, 06:32:11 amIf anyone is interested, I have attached a project ZIP (and screenshot). The program allows the user to enter 4 points using the mouse and displays the results. Thank you for posting the code.  Your code works with the points you selected but, unfortunately, it does _not_ work with the test points I suggested.Yes, it would appear my code works only in some conditions If the p1-p2 line is up & right (+x -y) it seems to work. cheers S. ---------------------------------------------------------------------- Paolo · 2021-02-06 09:07 the tabulated values on the bottom left of the screen shot ---------------------------------------------------------------------- avk · 2021-02-06 14:31 It seems purely geometric solution: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program sec_n_tang; {$mode objfpc}{$H+}{$modeswitch advancedrecords} uses  SysUtils, Math; type  TPoint2D = record    X,    Y: Float;    class function SamePoint(const L, R: TPoint2D): Boolean; static;    class function Distance(const L, R: TPoint2D): Float; static;    class function Middle(const L, R: TPoint2D): TPoint2D; static;    constructor From(aX, aY: Float);  end;   TLine2D = record    A,    B,    C: Float;    class function Intersect(const L1, L2: TLine2D): Boolean; static;    class function Intersection(const L1, L2: TLine2D): TPoint2D; static;    constructor From(aA, aB, aC: Float);  constructor From(aSlope, aIntercept: Float);    constructor From(const P1, P2: TPoint2D);    function Contains(const P: TPoint2D): Boolean;  function NormalThrough(const P: TPoint2D): TLine2D;    function AtDistFrom(const P: TPoint2D; aDist: Float): TPoint2D;    function Slope: Float;    function Intercept: Float;  end; { TPoint } class function TPoint2D.SamePoint(const L, R: TPoint2D): Boolean;begin  Result := SameValue(L.X, R.X) and SameValue(L.Y, R.Y);end; class function TPoint2D.Distance(const L, R: TPoint2D): Float;begin  Result := Sqrt(Sqr(L.X - R.X) + Sqr(L.Y - R.Y));end; class function TPoint2D.Middle(const L, R: TPoint2D): TPoint2D;begin  Result := TPoint2D.From((L.X + R.X)/Float(2), (L.Y + R.Y)/Float(2));end; constructor TPoint2D.From(aX, aY: Float);begin  X := aX;  Y := aY;end; { TLine } class function TLine2D.Intersect(const L1, L2: TLine2D): Boolean;begin  Result := not SameValue(L1.A * L2.B - L1.B * L2.A, Float(0));end; class function TLine2D.Intersection(const L1, L2: TLine2D): TPoint2D;var  v: Float;begin  v := L1.A * L2.B - L1.B * L2.A;  if SameValue(v, Float(0)) then    raise Exception.Create('Intersection cannot be found');  Result := TPoint2D.From((L1.B * L2.C - L1.C * L2.B)/v, (L1.C * L2.A - L1.A * L2.C)/v);end; constructor TLine2D.From(aA, aB, aC: Float);begin  A := aA;  B := aB;  C := aC;end; constructor TLine2D.From(aSlope, aIntercept: Float);begin  A := aSlope;  B := -Float(1);  C := aIntercept;end; constructor TLine2D.From(const P1, P2: TPoint2D);begin  if TPoint2D.SamePoint(P1, P2) then    raise Exception.Create('Line is undefined');  A := P2.Y - P1.Y;  B := P1.X - P2.X;  C := P1.Y * P2.X - P1.X * P2.Y;end; function TLine2D.Contains(const P: TPoint2D): Boolean;begin  Result := SameValue(A * P.X + B * P.Y + C, Float(0));end; function TLine2D.NormalThrough(const P: TPoint2D): TLine2D;begin  Result := TLine2D.From(B, -A, A * P.Y - B * P.X)end; function TLine2D.AtDistFrom(const P: TPoint2D; aDist: Float): TPoint2D;var  Sin, PY, PX: Float;begin  if SameValue(A, Float(0)) then    Result := TPoint2D.From(P.X + aDist, P.Y)  else    begin      Sin := A/Sqrt(Sqr(A) + Sqr(B));      PY := P.Y + aDist * Sin;      PX := -(PY * B + C)/A;      Result := TPoint2D.From(PX, PY);    end;end; function TLine2D.Slope: Float;begin  if SameValue(B, Float(0)) then    begin    if SameValue(A, Float(0)) then        Result := Float.NaN      else        if A > 0 then          Result := Float.NegativeInfinity        else          Result := Float.PositiveInfinity;    end  else    Result := -A/B;end; function TLine2D.Intercept: Float;begin  if SameValue(B, Float(0)) then    begin      if SameValue(C, Float(0)) then        Result := Float.NaN      else        if C > 0 then          Result := Float.NegativeInfinity        else          Result := Float.PositiveInfinity;    end  else    Result := -C/B;end; var  p1, p2: TPoint2D;  Tang: TLine2D; procedure ReadParams;var  X1, Y1, X2, Y2, Tx1, Ty1, Tx2, Ty2: Float;begin  X1 := 0;  Y1 := 0;  X2 := 0;  Y2 := 0;  Tx1 := 0;  Ty1 := 0;  Tx2 := 0;  Ty2 := 0;  WriteLn('Type the coordinates of the secant points - x1, y1, x2, y2'+          ' and the tangent - Tx1, Ty1, Tx2, Ty2 separated by spaces');  Write('>> ');  ReadLn(X1, Y1, X2, Y2, Tx1, Ty1, Tx2, Ty2);  p1 := TPoint2D.From(X1, Y1);  p2 := TPoint2D.From(X2, Y2);  Tang := TLine2D.From(TPoint2D.From(Tx1, Ty1), TPoint2D.From(Tx2, Ty2));end; procedure Calc;var  Chord, TangNorm, ChordNorm, AuxLine: TLine2D;  Center, ChordMid, AuxMid, Intsct, Tng1, Tng2: TPoint2D;  R: Float;begin  if TPoint2D.SamePoint(P1, P2) then    begin      WriteLn('There are an infinite number of solutions with given parameters.');      exit;    end;  if Tang.Contains(p1) and Tang.Contains(p2) then    begin      WriteLn('There is no solution with the given parameters.');      exit;    end;  Chord := TLine2D.From(P1, P2);  if Tang.Contains(p1) then    begin      WriteLn('Tangent point is the same as P1');      TangNorm := Tang.NormalThrough(P1);      if TangNorm.Contains(P2) then        Center := TPoint2D.Middle(P1, P2)      else        begin          ChordNorm := Chord.NormalThrough(TPoint2D.Middle(P1, P2));          Center := TLine2D.Intersection(TangNorm, ChordNorm);        end;      R := TPoint2D.Distance(Center, p2);      WriteLn('There is a single solution');    end  else    if Tang.Contains(p2) then      begin      WriteLn('Tangent point is the same as P2');        TangNorm := Tang.NormalThrough(P2);        if TangNorm.Contains(P1) then          Center := TPoint2D.Middle(P1, P2)        else          begin          ChordNorm := Chord.NormalThrough(TPoint2D.Middle(P1, P2));          Center := TLine2D.Intersection(TangNorm, ChordNorm);          end;      R := TPoint2D.Distance(Center, P1);        WriteLn('There is a single solution');      end    else      if TLine2D.Intersect(Tang, Chord) then        begin          WriteLn('There are two solutions');          Intsct := TLine2D.Intersection(Tang, Chord);          R := Sqrt(TPoint2D.Distance(P1, Intsct) * TPoint2D.Distance(P2, Intsct));        ChordMid := TPoint2D.Middle(P1, P2);          Tng1 := Tang.AtDistFrom(Intsct, R);          Tng2 := Tang.AtDistFrom(Intsct, -R);          AuxLine := TLine2D.From(Tng1, P1);          AuxMid := TPoint2D.Middle(Tng1, P1);          Center := TLine2D.Intersection(AuxLine.NormalThrough(AuxMid), Chord.NormalThrough(ChordMid));          R := TPoint2D.Distance(Center, P1);          WriteLn('First');          WriteLn('Tangent point: X = ', FloatToStr(Tng1.X), ', Y = ', FloatToStr(Tng1.Y));          WriteLn('Circle center: X = ', FloatToStr(Center.X), ', Y = ', FloatToStr(Center.Y));          WriteLn('Circle radius: ', FloatToStr(R));          AuxLine := TLine2D.From(Tng2, P1);          AuxMid := TPoint2D.Middle(Tng2, P1);          Center := TLine2D.Intersection(AuxLine.NormalThrough(AuxMid), Chord.NormalThrough(ChordMid));          R := TPoint2D.Distance(Center, P1);          WriteLn('Second');          WriteLn('Tangent point: X = ', FloatToStr(Tng2.X), ', Y = ', FloatToStr(Tng2.Y));        end      else        begin          WriteLn('Tangent and secant are parallel');          ChordNorm := Chord.NormalThrough(TPoint2D.Middle(P1, P2));          Tng1 := TLine2D.Intersection(Tang, ChordNorm);          AuxLine := TLine2D.From(Tng1, P1);          ChordMid := TPoint2D.Middle(Tng1, P1);          Center := TLine2D.Intersection(ChordNorm, AuxLine.NormalThrough(ChordMid));          R := TPoint2D.Distance(Center, P1);          WriteLn('There is a single solution');          WriteLn('Tangent point: X = ', FloatToStr(Tng1.X), ', Y = ', FloatToStr(Tng1.Y));        end;  WriteLn('Circle center: X = ', FloatToStr(Center.X), ', Y = ', FloatToStr(Center.Y));  WriteLn('Circle radius: ', FloatToStr(R));  WriteLn;end; var  Answer: string = ''; begin  repeat    Write('Press "c" key to continue or any other key to exit >> ');    ReadLn(Answer);    WriteLn;    if (Length(Answer) <> 1) or (LowerCase(Answer[1]) <> 'c') then      begin        WriteLn('Program exit.');        exit;      end;    ReadParams;    Calc;  until False;end. ---------------------------------------------------------------------- 440bx · 2021-02-06 15:08 @speter Quote from: speter on February 06, 2021, 10:03:45 amYes, it would appear my code works only in some conditions If the p1-p2 line is up & right (+x -y) it seems to work. It's good to know the limitations of a method. @Paolo Your program looks really good and the results appear to be correct .  I'm probably not the only one looking forward to your posting a Lazarus-compatible version of your code.   Any time estimate for it ? @avk You posted your code while I was typing this reply.  I'm going to try your program after posting this. ---------------------------------------------------------------------- Paolo · 2021-02-06 15:25 thanks 440bx, I am not at home at the moment. I'll prepare the code, it is quite compact. (I would like to provide you also the step-by- step derivation of such formulas), as for avk code it can find none, one or two solutions depending on the inputs. PS: can I upload an exe in forum ? if you want play with my GUI I have my componentes for numerical input and function plot, otherwise I'll extract just the code for coputation. @avk, it looks good job At the end to who asks for this topic we can say that there isn't a "simple" colose form to solve this problem, but you have to go trough some computation. ---------------------------------------------------------------------- 440bx · 2021-02-06 16:25 Quote from: Paolo on February 06, 2021, 04:25:03 pmI'll prepare the code, it is quite compact. (I would like to provide you also the step- by-step derivation of such formulas) looking forward to it Quote from: Paolo on February 06, 2021, 04:25:03 pmPS: can I upload an exe in forum ? if you want play with my GUI I have my componentes for numerical input and function plot, otherwise I'll extract just the code for coputation. I believe the forum won't allow a .exe file (I could be mistaken about that) but, you can always 7zip-it to work around that problem if necessary. Quote from: Paolo on February 06, 2021, 04:25:03 pm@avk, it looks good job Yes, @avk's solution looks very good.   It's been a number of years since I was involved in Geometry.  I didn't remember this formulaCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i R := Sqrt(TPoint2D.Distance(P1, Intsct) * TPoint2D.Distance(P2, Intsct)); ---------------------------------------------------------------------- Paolo · 2021-02-06 17:15 QuoteIt's been a number of years since I was involved in Geometry. me too, even if still involved in complicate computations in my job. just for fun: A man asked to a child : “ how many lines passes trough one point ?” (child)  : “I don’t know, maybe 1 or 2” (Man) : “No, you are wrong, they are infinite” (Man) :”..and how many lines passes trough 2 point ?” (Child) : “much, much more !” ---------------------------------------------------------------------- avk · 2021-02-06 17:17 Quote from: 440bx on February 06, 2021, 05:25:27 pm...I didn't remember this formulaCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i R := Sqrt(TPoint2D.Distance(P1, Intsct) * TPoint2D.Distance(P2, Intsct));Just look at the picture in this post. ---------------------------------------------------------------------- 440bx · 2021-02-06 17:31 Quote from: Paolo on February 06, 2021, 06:15:24 pmA man asked to a child : “ how many lines passes trough one point ?” (child)  : “I don’t know, maybe 1 or 2” (Man) : “No, you are wrong, they are infinite” (Man) :”..and how many lines passes trough 2 point ?” (Child) : “much, much more !” Pure logic : twice as many of course!  ...   Gotta love kids. ETA A mathematical mind would rephrase the question "... and how many lines pass through both points"... otherwise, the child is right, more lines pass through 2 points than just one.  (disregarding the fact that 2 * infinity = infinity) Quote from: avk on February 06, 2021, 06:17:38 pmJust look at the picture in this post. I had seen the picture you posted but, it didn't bring the theorem to mind. Good job on that program. ---------------------------------------------------------------------- Peter H · 2021-02-06 18:46 I solved the problem with the opensource CAS program MAXIMA respective wxMAXIMA. This are the required commands in MAXIMA: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i e1:(x1-cx)^2+(y1-cy)^2-cy^2 = 0;e2:(x2-cx)^2+(y2-cy)^2-cy^2=0;solve ([e1,e2], [cx,cy]);  (cx,cy) :Center coordinates of the circles (x1,y1) (x2,y2) :Two points. It solves the simpler case where a circle touches two points and the x axis. It is assumed the zeropoint of coordinate system is at the intersection of a line through both points and the abzissa (x axis) So to use the formulas, a coordinate transformation forward and backward is required. This are the results: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i cx=(sqrt(y1 *y2^3-2*y1^2*y2^2+(y1^3+(x2^2-2*x1*x2+x1^2)*y1)*y2)+x1*y2-x2*y1)/(y2- y1);cy=-((2*x2-2*x1)*sqrt(y1)*y2^(3/2)*sqrt(y2^2-2*y1*y2+y1^2+x2^2- 2*x1*x2+x1^2)-y2^4+y1*y2^3+(y1^2-x2^2+2*x1*x2-x1^2)*y2^2+((- x2^2+2*x1*x2-x1^2)*y1-y1^3)*y2)/(2*y2^3-4*y1*y2^2+2*y1^2*y2); cx=- (sqrt(y1*y2^3-2*y1^2*y2^2+(y1^3+(x2^2-2*x1*x2+x1^2)*y1)*y2)- x1*y2+x2*y1)/(y2-y1);cy=((2*x2-2*x1)*sqrt(y1)*y2^(3/2)*sqrt(y2^2- 2*y1*y2+y1^2+x2^2-2*x1*x2+x1^2)+y2^4-y1*y2^3+(-y1^2+x2^2- 2*x1*x2+x1^2)*y2^2+(y1^3+(x2^2-2*x1*x2+x1^2)*y1)*y2)/(2*y2^3- 4*y1*y2^2+2*y1^2*y2);  "cy" in this case is equal to the radius. ---------------------------------------------------------------------- Paolo · 2021-02-06 18:52 yes quite complicate if you ant express the result by inouts vales! but I don't like to see the division by (y2-y1), can you check if it works in such cases, ie P1.Y = P2.Y ! ---------------------------------------------------------------------- Peter H · 2021-02-06 19:12 Division trough y1-y2 is required, because in this case when it is zero we get one small circle and one circle with radius infinity. These special cases (there are others, where the result is geometric impossible and mathematical complex, sqrt(-1) ) must be tested before or captured by exceptions :No geometric solution possible in these cases. It must also be tested, if x1=x2=0 or and y1=y2=0 these are special cases to consider, a little bit of  thinking is still required. Hopefully in weekend I can make a command line test program with coordinate transformation included. I have not enough skills to make a graphical program fast.    Edit: Yes there is something special to consider: If y1-y2 = zero, then points are parallel to the x axis. in this case cx is undetermined and impossible to calculate. ---------------------------------------------------------------------- Paolo · 2021-02-06 19:40 Peter H, the case p1.y = p2.y is not a special case, it shoul be handled correctly. What has no sense is the case p1.x=p2.x and p1.y = p2.y that is p1=p2. ---------------------------------------------------------------------- Peter H · 2021-02-06 19:52 If both points are parallel to the tangent it is impossible to calculate the position of the circle, only the radius and the orthogonal distance to the tangent can be calculated. Edit: Oops something is wrong, you are right. I must think about it. Never trust to computer results and websites!  I believe, MAXIMA does not consider all special cases to the extent as Wolfram Alpha does. It is a free Open Source LISP program. If y1=y2 it is probably required to rotate the coordinate system by 90°, this means, swap x and y. ---------------------------------------------------------------------- Paolo · 2021-02-06 20:10 Even in the case p1=p2 and tangent passing trough them a circle of radius 0 and centre in p1 (=p2) could be considered a valid solution (?????) ---------------------------------------------------------------------- Paolo · 2021-02-06 20:22 I think so, if you try to write a complete formula you will find two (plus branches for soecial cases), one with division by y1-y2 and one with x1-x2, probably the software you have find just one of them. ---------------------------------------------------------------------- Peter H · 2021-02-06 20:54 I changed the formula and then it should deliver a result that avoids the problem. (Wolfram Alpha does it, but the free version has to much problems) However, then it calculates half an hour and delivers an empty result, this means: couldnt solve. Its not Mathematica ;-) Edit: Oops, after posting I found an errori in the input, a bracket is missing I try again. Now it finds a result, but the same. It is probably not possible or it must deliver more than 4 result formulas for all special cases and it doesnt do this. So this special case must be done programmatically x and y must be swapped and the numeric result also swapped I do however believe, the result is correct, because this program is used at technical and mathematical universities and so on. Edit2: Swap is not necessary. if y1=y2 then cx = (x1+x2)/2. and the result for cy is valid and the other circle has infinite radius and is a line through point 1 and 2. BTW, I solved the same equation with Wolfram Alpha, it gives te same solutions, but also the solutions for all special cases. Note, there is one box without result, this means there is no (real number) result for this case. https://www.wolframalpha.com/input/?i=solve+%28%28x_1- c_1%29%5E2%2B%28y_1-c_2%29%5E2%3D%28x_2-c_1%29%5E2%2B%28y_2- c_2%29%5E2%3Dc_2%5E2%29+for+c_1%2Cc_2 ---------------------------------------------------------------------- Peter H · 2021-02-07 01:19 Quote from: Paolo on February 06, 2021, 09:22:08 pmI think so, if you try to write a complete formula you will find two (plus branches for soecial cases), one with division by y1-y2 and one with x1-x2, probably the software you have find just one of them. The quotient does not go to infinity, there is a singularity, a "hole" in the equation, for one circle, while the other circle has infinite radius. I calculate a circle that touches 2 Points and the x-axis. If I would calculate for 2 points and touching the y axis, then x1-x2 would be in the nominator of the quotient. If I would set y1=y2 before I solve the equation, I would get another solution, where the mathematical singularity is eliminated : c_1 = 1/2 (x_1 + x_2) and c_2 = (x_1^2 - 2 x_2 x_1 + x_2^2 + 4 y_2^2)/(8 y_2) and y_1 = y_2 and x_2 - x_1!=0 and y_2 !=0 where "c_1" is the x value of the center and "c_2" the y value (Wolfram doesnt accept characters in the suffix) If the computer would know, that 0^2 and 0 are different (in geometry), no singularity would exist.  (You can see in the expression that the numerator has potenzes and products, but not the nominator) Mathematically, 0m*0 is 0m and NOT 0. (0m)^2/(0m) = 0m, but (0m)/(0m) = Singularity and is dimensionless,, at least in technical calculations, because all technical numbers are not plain numbers, but have dimensions. And in geometry we have dimensions. You are not allowed to separate number and dimension, but the computer does this and gets confused. With the method of partial fraction decomposition a formula without singularity possibly could be made, but this would be ineffizent and awkward to calculate. Edit2: (0m)^2/(0m) = xyzm.     xyz is determined, because the dimension is known.    xyz is -infinity to +infinity and can/must be calculated by other formulas. Probably it is the best, if the angle for the line trough Point1 and Point2 is smaller tha 45° then swap x and y of the arguments and the result. This is equivalent to a coordinate rotation by 90°. This avoids the singularity and vastly improves numeric stability. If you stiill get an exception, then you have sqrt(-1) somewhere and there is no geometric result possible. Or Point1 and Point2 are the same and in this case there is an infinite amount of results. ---------------------------------------------------------------------- speter · 2021-02-07 05:57 Well my little program now works (I believe) I've even added zooming and cartesian coordinates.  My error turned out to occur when the tangent line passes "behind" the circle cord; and was solved by checking that and if necessary swapping the circle cord points. cheers S. ---------------------------------------------------------------------- 440bx · 2021-02-07 06:33 Quote from: speter on February 07, 2021, 06:57:33 amWell my little program now works (I believe) Looks good.  Definitely looks like it works. ---------------------------------------------------------------------- avk · 2021-02-07 06:43 Quote from: 440bx on February 06, 2021, 06:31:30 pmGood job on that program. Thanks. BTW, there was a bug in it, which I hope I fixed. ---------------------------------------------------------------------- Paolo · 2021-02-07 10:29 Thanks to all, maybe we need a dedicated math page on the forum (?). (I am interested on an algorithm to find the minimum sphere enclosing some given points, maybe next time I'll open a dedicated topic) . Soon my code and program. ---------------------------------------------------------------------- speter · 2021-02-07 10:39 Quote from: Paolo on February 07, 2021, 11:29:11 am(I am interested on an algorithm to find the minimum sphere enclosing some given points, maybe next time I'll open a dedicated topic) .Easy (famous last words ) calculate the "extents" (min/max enclosing cube(?)) that gives you the centre; calculate the dist from the centre to each of the points and the max-dist is your radius. cheers S. ---------------------------------------------------------------------- Paolo · 2021-02-07 10:45 I don't think is so easy. ---------------------------------------------------------------------- 440bx · 2021-02-07 17:15 Quote from: Paolo on February 07, 2021, 11:45:09 amI don't think is so easy. At first I thought so too.  I thought it would require calculating the convex hull of the set of points and the smallest circle resulting from it but, then I tried @speter suggestion and it definitely looks like the resulting circle (or sphere) is smaller because the enclosing rectangle (or cube) is the smallest enclosing geometric shape. Attached is a screenshot that compares the circles obtained using both methods and the Geogebra script I used.  Note that the convex hull was calculated "manually" because Geogebra does not have a function to determine it. The resulting convex hull circle is in blue and the resulting rectangle circle is a brown reddish color. ---------------------------------------------------------------------- Paolo · 2021-02-07 17:34 @440bx, in your screenshot what is the circle with samllest radius ? if it is the dash-red circle, if I understood right, it seems not touching at least 3 points (not necessary condition, but typical), so it si not the minimum radius circle ! I think... Sometime ago I found the code in pascal for the circle case, I'll search it in my HD. ---------------------------------------------------------------------- Paolo · 2021-02-07 17:40 Now I rememebr, here the link for the solution. it was the delohi-for-fun web site, still active ? s lot of intersting code in pascal. http://delphiforfun.org/Programs/circle_covering_points.htm ---------------------------------------------------------------------- 440bx · 2021-02-07 17:41 Quote from: Paolo on February 07, 2021, 06:34:54 pm@440bx, in your screenshot what is the circle with samllest radius ? Good question!  I was going to post a correction when I saw your post.  I am correcting the attachments to the previous post.  (Hopefully, this time I got it right.) The radius of the circle determined using the square is smaller than the (hopefully correct now) smallest radius obtained using the convex hull. ---------------------------------------------------------------------- Paolo · 2021-02-07 17:41 maybe betteer open another topic for this discussion. ---------------------------------------------------------------------- 440bx · 2021-02-07 17:42 Quote from: Paolo on February 07, 2021, 06:41:32 pmmaybe betteer open another topic for this discussion. Probably ---------------------------------------------------------------------- Paolo · 2021-02-07 17:43 ok, I'll open a new topic for that ---------------------------------------------------------------------- Paolo · 2021-02-07 17:46 done, open a new topic but I still have to make public my code for the present topic, I promise for tomorrow ! ---------------------------------------------------------------------- 440bx · 2021-02-07 17:50 Quote from: Paolo on February 07, 2021, 06:46:30 pmdone, open a new topic The link you posted solves the problem because of that I'm not sure a new topic is warranted.  Definitely an interesting problem and solution. Quote from: Paolo on February 07, 2021, 06:46:30 pmbut I still have to make public my code for the present topic, I promise for tomorrow ! Whenever is good for you.   It will be nice to look at your implementation. ETA: The link solves the problem in 2D not 3D, therefore a new topic is likely warranted. ---------------------------------------------------------------------- Peter H · 2021-02-09 06:40 If "My given Points" have these coordinates in Paolos speter's program: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  //-------- ---------------------------------------------------------procedure TForm1.Button_my_given_pointsClick(Sender: TObject);//---------------- -------------------------------------------------var  a : byte;begin  label_msgs.caption := 'here is a simple one :)';  initialise;   p[1].setv(300.0,400.0, 'p[1] on circle');    // 2 pts on circle circumferance  p[2].setv(500.0,400.0, 'p[2] on circle');   p[3].setv(100.0,100.0, 'p[3] on tangent');   // 2 pts defining a tangent line  p[4].setv(700.0,100.0, 'p[4] on tangent');   memo1.Append('given points:');  for a := 1 to 4 do    memo1.Append('  '+p[a].tostring);   do_calcs(true);end;     the program crashes with an exception. In this case the secant and the tangent are parallel and a solution with the intersecting secant-tangent method is impossible. The same is with my formula, when I have (after the coordinate transformation) "y2-y1"=0 in the denominator. In this case another method must be used to calculate the first circle and a solution for the second circle does not exist, because it has infinite radius. If you, in your mind, rotate the coordinate system, you should see, there is an  infinite amount of other situations, where this can happen. Therefore I still think, my method is better, because after the coordinate transformation this singular special case and other special singular cases are very easy to detect. However, I still did not write a program, because I was busy to study and understand the theoretical problem. The program is elegantly written and easy to read and well documented, thank you for this, unfortunately this does not prevent conceptual bugs. This problem and other singular problems are not so easy to detect and solve with the intersecting secant-tangent method. The easiest way to solve the problem, is probably use Mathematica (expensive, but cheaper than Delphi),  this emits  C code. ---------------------------------------------------------------------- Paolo · 2021-02-09 15:24 @ Peter H, probably you are confusing me with other people in the forum, not yet given my code ! but... look at the picture, I have finisched the GUI and all "seems" fine. I am late with code because I need to correct some typos, very soon the code and a note on the math behind it. see you soon @Peter H, yes there could be a dangerous division by DY, but you can avoid that using formula with DX insted of DY ! ---------------------------------------------------------------------- Peter H · 2021-02-09 15:49 Ok, the other problems I have seen: If one of the two points is on the tangent, then a geometrical solution is not possible unless the other point is orthogonally to the intersection. The program doesnt recognise this and draws a circle that intersects the tangent. If both points are on different sides of the tangent. Then also a geometric solution is impossible, but the program draws the circles intersecting the tangent. In this case my formula should deliver an exception because it calculates sqrt(-xyz). When the coordinate system is transformed as I described before, I have only to check: if abs(Y1) < epsilon or abs(Y2) < epsilon then //test if other point is orthogonal above, if not, geometric solution impossible. if sign(y1) <> sign(Y2), //geometric solution impossible  to detect these special situations. In both cases the mathematic formula should deliver a complex result "sqrt(-xyz)" or an exception The final test should be If( (Y1-Y2)^2+(X1-X2)^2 < epsilon  then //Points too close together, result is unstable or gives exception. ---------------------------------------------------------------------- Paolo · 2021-02-09 15:59 @Peter H, if one point (only one !) of circle is also one point of the tangent the solution is easier : there is just one circle (or two coincidents, it depends how you see the thing). Look at the example in the picture ---------------------------------------------------------------------- Peter H · 2021-02-09 16:05 Correct, only the other circle is impossible, it will intersect the tangent. If the secant is not orthogonal to the tangent, both circles are impossible. Edit oops - confusing, but easier to solve with transformed coordinates. Edit: If one point is on the tangent, and the secant is orthogonal to the tangent, two circles are mathemathically possible but they will be identic. My formula would deliver an sqrt(-xyz) exception when the second circle is calculated but this can also be detected and prevented. If I work with transformed coordinates, I have not to test orthogonality but only verticality, because the transformed tangent is always horizontal. The intersecting tangent-secant method was described and proofen by Euklid 300 years before Anno 0. ;-) See Wikipedia. The mathematic method is equivalent to the geometric method, because classic geometry is 100% solved today in mathemathics, for each geometric rule and axiom there is a mathematic and logic equivalent Therefore a mathematic solution is superior beause: It will give a sqrt(-1) or 1/0 exception if a tried solution is impossible, or if the solution must be found with another method than intersecting tangent-secant. Quote from: Paolo on February 09, 2021, 04:24:27 pm@ Peter H, probably you are confusing me with other people in the forum Excuse me for this. I do not confuse people. This is the internet, nobody really knows anyone. I care about the truth here, not about people. (I care about people I know, but nothing more) I did not tightly follow the discussion, because I had another (IMHO better) solution in mind that was not accepted by the community, and therefore I dont remember who wrote the program. Error corrected above.  If the public power supply fails. all this discussion about algorithms and programing languages and the internet is over, dont forget this. ---------------------------------------------------------------------- avk · 2021-02-10 05:47 Quote from: Peter H on February 09, 2021, 05:05:47 pm... The mathematic method is equivalent to the geometric method, because classic geometry is 100% solved today in mathemathics, for each geometric rule and axiom there is a mathematic and logic equivalent Therefore a mathematic solution is superior beause: ... That is, geometry is no longer mathematics? ---------------------------------------------------------------------- Paolo · 2021-02-10 08:38 dear all, in the following: my TN (Technical Note) on the involved math the Lazarus code (sorry not input check or plots because based on my components) PS:I see the size limitation in file dimension, how to share larger file of about 1-2MB ? (=the runnign code with GUI) ---------------------------------------------------------------------- Paolo · 2021-02-10 08:39 the code ---------------------------------------------------------------------- Paolo · 2021-02-10 12:36 I see now that my TN was't uploaded, this evening I'll upload the TN. Sorry for the mistake. ---------------------------------------------------------------------- Paolo · 2021-02-10 15:51 the TN ...