I have three points $A, B, C$ and I would like to find the three closest points $A', B', C'$ that
- Cause $\vec{A'B'}$ to be perpendicular to $\vec{B'C'}$ and
- Minimize the sum-square error between corresponding points $\epsilon = \lvert A' - A\rvert^2 + \lvert B' - B\rvert^2 + \lvert C' - C\rvert^2$
Since I know(?) that the best points will be in the same plane as the original points, I approached the formulas for the best points by using the original points as origins and bases:
$A' = A + t_{AA}(A - B) + t_{AC}(C - B)$
$B' = B + t_{BA}(A - B) + t_{BC}(C - B)$
$C' = C + t_{CA}(A - B) + t_{CC}(C - B)$
If I assume I know $A', B', t_{CC}$, I can compute $t_{CA}$ by applying the perpendicularity constraint via a zero-valued dot product:
$0 = (A' - B') \cdot (C' - B')$
...which leads to (if I figure correctly):
$t_{CA} = -\frac{(A' - B') \cdot (C - B') + t_{CC} (A' - B') \cdot (C - B)}{(A' - B') \cdot (A - B)}$
Since only the $\lvert C' - C\rvert^2$ part of $\epsilon$ is affected by by $t_{CC}$, I should be able to compute $t_{CC}$ by minimizing error:
$\frac{\partial}{\partial t_{CC}}[\lvert C' - C\rvert^2] = 0$
I can sort of get a result from solving the above using $\lvert C' - C\rvert^2 = (C' - C) \cdot (C' - C)$, but my Mathematica-foo is not strong enough to get a concise expression for $t_{CA}$ that eliminates $t_{CC}$. Then, I figure I would need to repeat that process 4 more times to find one of the $t_{xx}$ scalars as a function of only the knowns $A, B, C$.
Is there a better way to compute $A', B', C'$ and/or is someone better able to use Mathematica than me? I want to find expressions for $A', B', C'$ that only use the knowns $A, B, C$.
Take a point $A'$ lying on a circle of radius $r_1$ centered at $A$, such that the radius vector $AA'$ makes an angle $\theta_1$ with the positive direction of the $x$ axis. And take a point $C'$ lying on a circle of $r_2$ centered at $C$ such that the radius vector $CC'$ makes an angle $\theta_2$ with the positive direction of $x$ axis. Then we have
$ A' = A + r_1 (\cos \theta_1, \sin \theta_1 ) $
$ C' = C + r_2 (\cos \theta_2, \sin \theta_2 ) $
Since we $A'B'$ to be perpendicular to $B'C'$, then this means that $B'$ lies on a circle whose center is the midpoint of $A'C'$ and whose radius is $\dfrac{1}{2} \overline{A'C'} $. Further, we want $B'$ to be closest to $B$
Hence, if we let
$ M = \dfrac{1}{2} (A' + C') $
And
$ \theta_3 = \text{atan2}( B_x - M_x, B_y - M_y ) $
(Note that the order of the parameters for $atan2$ is reversed in some computer languages. The convention I am using, is $ \phi = \text{atan2}(u, v)$ retruns an angle $\phi$ such that $\tan \phi = \dfrac{v}{u} $.)
And finally,
$ R = \dfrac{1}{2} \| A' C' \| $
Then
$B' = M + R ( \cos \theta_3, \sin \theta_3 ) $
Note that the distance $r_3 = \| B B ' \| = \| B M \| - R $
Now the function we want to minimize is
$ f = r_1^2 + r_2^2 + r_3^2 $
And we four variables $r_1, \theta_1, r_2 , \theta_2 $. To carry out the minimization, I resorted to numerical methods, in particular the simple and very basic algorithm named steepest descent. This algorithm requires the gradient vector $\nabla f = [ \dfrac{\partial f }{\partial r_1} , \dfrac{\partial f }{\partial \theta_1} ,\dfrac{\partial f }{\partial r_2} , \dfrac{ \partial f}{\partial \theta_2} ]^T$.
This can be obtained by numerical differentiation.
The code I've developed is listed below, followed by the converged triangle $A'B'C'$. The points $A,B,C$ are the vertices of a 13-14-15 triangle.