[Click here for a PDF version of this post]


In Jim Smith’s recent Handling Rejection! Using Geometric Algebra to Find the Incircle of a Triangle video, he uses an area argument to find the center point of a circle inscribed in a triangle, as illustrated in fig. 1.

fig. 1. Triangle with inscribed circle.

fig. 1. Triangle with inscribed circle.

In the video, Jim mentioned that he first tried calculating the intersection of the bivectors, but didn’t like the form of the solution. I’m curious what aspect of that solution wasn’t desirable, since it is a pretty compact way to solve the system.


A very convenient way to describe a triangle is with a pair of vectors for two of the edges, say \( \Ba, \Bb \), where the third edge is \( \Bc = \Ba -\Bb \). In Jim’s problem, he started with the scalar lengths of all the edges \( a, b, c \). The two representations are interchangable. We can set
\Ba &= a\Be_1 \\
\Bb &= b \Be_1 e^{i\theta_c},
where \( i = \Be_1 \Be_2 \), and \( \theta_c \) is the angle opposite edge \( \Bc \), which can be found from the cosine law
\Bc^2 = \lr{ \Ba – \Bb }^2 = \Ba^2 + \Bb^2 – 2 \Ba \cdot \Bb = a^2 + b^2 – 2 a b \cos\theta_c,
\theta_c = \cos^{-1} \lr{ \frac{a^2 + b^2 – c^2}{2 a b} }.

The center point.

The points on our bisectors are
r_c(t) &= t \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } \\
r_b(t) &= \Ba + t \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} } \\
r_a(t) &= \Bb + t \lr{ \mathbf{\hat{c}} – \mathbf{\hat{b}} }.
We can find the intersection of any two of these to find the center point of the circle. For example, we seek solutions of
u \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } = \Ba + v \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} }.
We can wedge this with either of the \( u, v \) vector factors, to eliminate one of the scalars in this equation. Seeking \( u \), we wedge with \( \mathbf{\hat{a}} + \mathbf{\hat{c}} \), for
u \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} } \wedge \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } = \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} } \wedge \Ba = \mathbf{\hat{c}} \wedge \Ba.
\Bz = \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } \lr{ \lr{ \mathbf{\hat{c}} \wedge \Ba } \cdot \inv{ \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} } \wedge \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } } }.
Having found the center, we can calculate the radius that touches the \( a \) edge, which is just
\mathrm{Rej}_{\Ba}(\Bz) = \lr{ \Bz \wedge \mathbf{\hat{a}} } \cdot \mathbf{\hat{a}}.
The scalar radius is
r = \Norm{ \Bz \wedge \mathbf{\hat{a}} }.


Using a Mathematica Manipulate, I plotted this solution, employing a duality transformation to calculate the bivectors using cross products (avoiding any GA package dependencies.)

For the radius, we need only:
r = \Norm{ \Bz \cross \mathbf{\hat{a}} }.

For the intersection, we can use:
\Bz = \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } \lr{ \lr{ \mathbf{\hat{c}} \cross \Ba } \cdot \inv{ \lr{ \mathbf{\hat{a}} + \mathbf{\hat{c}} } \cross \lr{ \mathbf{\hat{a}} + \mathbf{\hat{b}} } } }.

In retrospect, just using a ratio of the determinants of the coordinates would have been a direct representation of the ratio of the wedge products, so I could have done that instead to translate the results from GA to Mathematica (since this is a planar problem.)  The wedge products could have also been encoding using complex numbers (in the newest version of the notebook, I’ve done that.)

Of course, using Mathematica, we could have just used it’s more general \( \textrm{Solve} \) function, and need not grow our own wedge product based implementation.