14
$\begingroup$

Good afternoon everyone! I am facing a problem which is straining my memory of linear algebra. I have:

  • Three points with known coordinates, forming a triangle in space. Let the coordinates be R(top), P(left bottom) and Q(right bottom) (only rough positions)
  • I'm not interested in the triangle as such, but in its two lines QP and QR
  • These lines are tangent to a circle of known radius (basically I'm trying to smooth the angle via a radius, like in CAD)

I need the equation of the circle, so I can pick any point I want between P and R to smooth out the angle. The angle is <180°, so there should exist one solution (correct me if I'm wrong)

I found an image which illustrates my problem:

You can see my points R,P,Q, aswell as my circle which is tangent to both rays originating in Q. Please note, that PQ does not necessarily have to be horizontal and that the angle $\alpha$ is not always 50°. My goal is to calculate the origin O and thus the complete equation of my circle in the form $\vec{r}(t)=\vec{c}+r\cdot\cos{\varphi}\cdot\vec{a}+r\cdot\sin{\varphi}\cdot\vec{b}$

Plan I have made so far:

  1. Calculate $\vec{PR}$
  2. Calculate $a=\arccos{\frac{\vec{QP}\bullet\vec{QR}}{\left|\vec{QP}\right|\cdot\left|\vec{QR}\right|}}$
  3. Calculate $b=\frac{\pi}{2}-a$

From here on it gets tricky. I know, that the origin is on the ray seperating the angle in Q in exact half. If I project that ray on my line $\vec{PQ}$, will I end up in the exact middle? Couldn't I just do something like "rotate $\frac{\vec{PR}}{2}$ around an axis through P by b degrees ccw, where the axis is perpendicular to the triangles plane"

I start to get lost here.

  • The perpendicular vector would be $\vec{QP}\times\vec{QR}$, wouldn't it?
  • The German Wikipedia suggests for rotating via an rotation-matrix $R_{\hat{n}}(\alpha)\vec{x}=\hat{n}(\hat{n}\cdot\vec{x})+\cos\left(\alpha\right)(\hat{n}\times\vec{x})\times\hat{n}+\sin\left(\alpha\right)(\hat{n}\times\vec{x})$ where $\vec{n}$ is the unity-normal-vector around which to rotate. Can I use this formula?
  • How do I finally compile my circle-equation?

Edit: And yes, I have seen this, but it didn't help :-)

$\endgroup$
4
  • $\begingroup$ R and P should not belong to the circle, as it makes the drawing confusing. $\endgroup$ Commented May 16, 2014 at 13:07
  • $\begingroup$ Well, R and P are the points the lines are tangent to the circle in. This is not my sketch anyway, I found it while researching my problem and found it quite handy. $\endgroup$ Commented May 16, 2014 at 13:09
  • $\begingroup$ If P and R are defined the problem is over constrained. If the radius is defined also, it is super over constrained.You can get the radius from the distance QR using the triangle $QOR$ $\endgroup$ Commented May 16, 2014 at 13:24
  • $\begingroup$ I suppose the image I chose is quite confusing after all. And my description aswell. I use the radius to roughly(!) create points P and Q. That doesn't make very much sense either now, does it? $\endgroup$ Commented May 16, 2014 at 13:30

5 Answers 5

18
$\begingroup$

What you want is the tangent, tangent, radius algorithm. One way to handle this is as follows:

  1. Measure the angle $\alpha = \widehat{RQP}$. This is done using the cross product and dot product from the coordinates of the points.
  2. Construct the bisector of the angle and note that if the radius is known as $h$ the distance from the vertex to the circle center $QA$ is $$s=\frac{h}{\sin \frac{\alpha}{2}}$$
  3. Numerically create a vector of length $s$ along $QR$ and rotate it by $\frac{\alpha}{2}$ to find point $A$.

TTR

$\endgroup$
9
  • $\begingroup$ That looks lovely, I'll give it a try! Do you have a hint on how to rotate a vector "easyly"? $\endgroup$ Commented May 16, 2014 at 13:26
  • $\begingroup$ $(x',y') = (x \cos \theta - y \sin \theta, x \sin \theta + y \cos \theta)$ $\endgroup$ Commented May 16, 2014 at 14:19
  • $\begingroup$ That pointed me the right direction. Although I did choose a slightly different implementation this is the best answer to my question. Thank you! $\endgroup$ Commented May 22, 2014 at 6:48
  • 1
    $\begingroup$ O = Q. I suppose I made a typo. And s=AQ $\endgroup$ Commented Nov 1, 2016 at 17:10
  • 1
    $\begingroup$ @PierrePaquette - I never said point B lies on the circle. $\endgroup$ Commented Oct 19, 2023 at 1:54
2
$\begingroup$

Another way to solve this, if you know the radius $r$, is to offset the two tangent lines by that amount and find where they intersect. That would be the center of the circle.

Here is an example with GeoGebra (of course)

geo

The dark black lines are the original lines, and the light gray lines are offset by one radius. Where they intersect is the center of the corner radius (red).


Here is a graphical representation of some C# code I did to implement this algorithmically.

fig2

and the code that does the TTR algorithm

public enum CornerSolution
{
    Inside,
    Opposing,
    Outside1,
    Outside2,
}


public static class Geometry
{
    public static Vector2 TanTanRadius(Vector2 apex, Vector2 side1, Vector2 side2, float radius, CornerSolution corner = CornerSolution.Inside)
    {
        Line2 edge1 = Line2.FromTwoPoints(apex, side1);
        Line2 edge2 = Line2.FromTwoPoints(apex, side2);

        int s1 = 0, s2 = 0;

        switch (corner)
        {
            case CornerSolution.Inside:
                s1 = 1;
                s2 = -1;
                break;
            case CornerSolution.Opposing:
                s1 = -1;
                s2 = 1;
                break;
            case CornerSolution.Outside1:
                s1 = 1;
                s2 = 1;
                break;
            case CornerSolution.Outside2:
                s1 = -1;
                s2 = -1;
                break;
        }

        Line2 offset1 = edge1.Offset(s1*radius);
        Line2 offset2 = edge2.Offset(s2*radius);

        return Point2.Meet(offset1, offset2).ToVector();
    }
}

The key implementations here are

  • Define a line from two points. A line is defined with three coefficients a, b, c, such that a*x+b*y+c=0 is the equation for the line.

     public static Line2 FromTwoPoints(Vector2 r1, Vector2 r2)
     {
         return new Line2(
             a: r1.Y-r2.Y,
             b: r2.X-r1.X,
             c: r1.X*r2.Y-r1.Y*r2.X);
     }
    
  • Offset a line parallelly. The c coefficient of the line defines the distance from the origin (in a way) and by adding to it, you create a parallel line:

     public Line2 Offset(float distance)
     {
         float ab = (float)Math.Sqrt(a*a+b*b);
         return new Line2(
             a, b, c-distance*ab);
     }
    
  • Find the point where two lines meet. Points are defined with three coordinates u, v, w (in homogeneous fashion)

     public static Point2 Meet(Line2 l, Line2 m)
     {
         return new Point2(
             u: l.B*m.C-m.B*l.C,
             v: m.A*l.C-l.A*m.C,
             w: l.A*m.B-m.A*l.B);
     }
    
  • Get point vector from homogeneous coordinates. The (x,y) coordinatees of a point are found by dividing (u,v) with w

     public Vector2 ToVector() => new Vector2(Vector.X/W, Vector.Y/W);
    
$\endgroup$
6
  • $\begingroup$ Hey John, can you please expand on this answer? I am trying to imagine how it would work, but coming up short. How do you calculate the direction to offset the individual lines in? $\endgroup$ Commented Feb 12, 2022 at 20:21
  • $\begingroup$ @TomášHübelbauer - are you calculating things algebraically, or geometrically? $\endgroup$ Commented Feb 12, 2022 at 22:32
  • 1
    $\begingroup$ @TomášHübelbauer - see edits above in my answer. I hope it is clear now. You can play with GeoGebra to see for yourself. $\endgroup$ Commented Feb 12, 2022 at 22:46
  • $\begingroup$ This looks like the solution with the least trigonometry (i.e. fastest and most accurate for an inaccurate PC), but the Geogrbra example doesn't really explain how to implement this programmatically, just mathematically. $\endgroup$ Commented Mar 18 at 19:00
  • 1
    $\begingroup$ I already found another answer and used it to make this very optimized (OpenSCAD) formula: px1 = line1[0].x+line1[1].y*radius, py1 = line1[0].y-line1[1].x*radius, px2 = line2[0].x+line2[1].y*radius, py2 = line2[0].y-line2[1].x*radius, den = line1[1].x*line2[1].y-line2[1].x*line1[1].y, k1 = (line2[1].y*(px2-px1)-line2[1].x*(py2-py1))/den, cx = px1+k1*line1[1].x, cy = py1+k1*line1[1].y. No square root involved. $\endgroup$ Commented Mar 31 at 19:33
1
$\begingroup$

I would suggest something like this to find the center of your circle: Since you know the coordinates of $P$ and $Q$, you can find a normalized vector that is perpendicular to $\vec{QP}$, using the inner product. You also said that $PQ$ is a tangent line meaning, the vector $\vec{PO}$ is perpendicular to $\vec{PQ}$. Given the fact you can calculate a vector perpendicular to $PQ$ means you only have to travel along this vector over a lenght of your (known) radius. If you start in $P$ you will end up exactly at the center of your cirlce.

$\endgroup$
2
  • $\begingroup$ Ah yes. I was wondering if I could use the dot-product, but somehow I am lost on how to calculate this normal vector. The dot-product would give me $a_1b_1+a_2b_2+a_3b_3$. There are a great many variables in that aren't there? In the end I want to program a general solution, so I would have to solve any equations symbolically first to keep calculation time low. $\endgroup$ Commented May 16, 2014 at 13:13
  • $\begingroup$ @lhiapgpeonk You were speaking of a triangle, wich is a two-dimensional object living in a certain plain, meaning the dot product wil result in a single vector. To succesfully do this you need to calculate the plain you are in first. This would result in more calculations, yes. But eventually the can be transformed in to formulae depending only on your three point and you radius. $\endgroup$
    – gebruiker
    Commented May 16, 2014 at 13:22
1
$\begingroup$

There is no unique solution to this problem. There are infinitely many circles which will be tangent to the two given lines. The centre's of these circles, as pointed in the solution given, will be on the angle bisector. See the animation below:

enter image description here

$\endgroup$
1
  • 2
    $\begingroup$ The OP mentioned they want a circle of a known radius. $\endgroup$ Commented Feb 12, 2022 at 20:20
0
$\begingroup$

enter image description here

Consider the given circle with the radius $r_1$ as a scaled version of the inscribed circle of the given $\triangle ABC$ with the inradius $r$. Then we have a scaling factor

\begin{align} k&=\frac {r_1}r , \end{align}

and the center of the given circle is \begin{align} I_1&=B+k\cdot\vec{BI} . \end{align}

Reminder: the center of the inscribed circle in terms of the points $A,B,C$ and side lengths $a,b,c$ is found as

\begin{align} I&=\frac{a\,A+b\,B+c\,C}{a+b+c} , \end{align}

and the tangential points of the incircle \begin{align} A_t&=\tfrac12\cdot(B+C)+\frac{b-c}{2a}\cdot(B-C) ,\\ C_t&=\tfrac12\cdot(A+B)+\frac{a-b}{2c}\cdot(A-B) . \end{align}

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .