This project is read-only.

Helmert, Affine Transformations for Overdetermined Models

Oct 1, 2010 at 3:44 PM

Hi, first off I must state that is a great, well-thought-out package.  Well done!

I see that there are Helmert and Affine classes that work for standard 3-point problems.  Is there a way to adapt these to N-point problems where we need to consider error?  I've found some papers defining a variety of solutions to this problem. gives a nice solution (actually a few), but I'm not sure how to approach solving it with your library.

I come from a computer science background.  I can read these papers, but I am dealing with a steep personal learning curve.



Oct 22, 2010 at 12:04 PM

Hi Rob,

Sorry for my long answering time, I´m currently very busy :-). The posted paper is quite nice. Please specifie your problems in detail, so I´m able to help you.

Thanks for using my library.

Kind regards




Nov 24, 2010 at 5:45 PM

Our data are (X,Y,Z) points described in 2 coordinate systems.  We have N points (usually N is 10-15 points) that we can use to determine transformation, rotation, and (optionally) scale from one coordinate system to another.

Our data is being tested against an Excel sheet.  The Excel sheet gives very good convergence after a short period of time.  It takes 6 input parameters to represent rotations and transformations and solves.  Given the solution, we can reliably convert any (XYZ) point from one coordinate system to another.

I have tried the PrincipalAxisMultidimensionalOptimizer, and the HookeJeevesOptimizer.  Neither have great results.

For each of those, I pass either a 6, 7, or 9 dimension vector representing (in order) transforms, rotations, and either no scale, constant scale, or different scales in each dimension.

The routine that your optimizer works on, takes the vector and applies standard Matrix operations to calculate transforms, rotations, scales.  The rotation matrix is skew symmentric.  The scale matrix is inverted, as is described in the paper.

Both optimizers take a long time to converge, and results do not appear "good" in comparison to the Excel sheet and what I mentioned.  The intent it to retire the Excel sheet, but I cannot do that yet.  The code that the optimizer calls (that does the meat of the work) is as follows:

                private Point3D calculateResult(int i, SquareMatrix W, SquareMatrix R, Matrix T)
                        Matrix m1 = R * new Matrix(m_input[i]).Transpose();
                        Matrix m2 = W * m1;
                        m2 = m2.Transpose();
                        Matrix m3 = m2 + T;
                        Point3D result = new Point3D();
                        result.X = m3.GetValueAtPosition(0, 0);
                        result.Y = m3.GetValueAtPosition(0, 1);
                        result.Z = m3.GetValueAtPosition(0, 2);
                        return result;

                private static void calculateMatrices(GeneralVector solution, out SquareMatrix W, out SquareMatrix R, out Matrix T)

                        T = new Matrix(1, 3);
                        T.SetValueAtPosition(0, 0, solution[6]);
                        T.SetValueAtPosition(0, 1, solution[7]);
                        T.SetValueAtPosition(0, 2, solution[8]);

                        W = new IdentityMatrix(3);
                        W.SetValueAtPosition(0, 0, 1.0 / solution[3]);
                        W.SetValueAtPosition(1, 1, 1.0 / solution[4]);
                        W.SetValueAtPosition(2, 2, 1.0 / solution[5]);

                        Matrix S = new SquareMatrix(3);
                        S.SetValueAtPosition(0, 0, 0.0);
                        S.SetValueAtPosition(1, 0, -solution[2]);
                        S.SetValueAtPosition(2, 0, solution[1]);
                        S.SetValueAtPosition(0, 1, solution[2]);
                        S.SetValueAtPosition(1, 1, 0.0);
                        S.SetValueAtPosition(2, 1, -solution[0]);
                        S.SetValueAtPosition(0, 2, -solution[1]);
                        S.SetValueAtPosition(1, 2, solution[0]);
                        S.SetValueAtPosition(2, 2, 0.0);
                        Matrix I3 = new IdentityMatrix(3);
                        Matrix r0 = I3 - S;
                        Matrix r1 = I3 + S;
                        Matrix ir0 = InverseMatrix.FromMatrix(new SquareMatrix(r0));
                        R = new SquareMatrix(ir0 * r1);

                protected double calculateLeastSquareResidiums(GeneralVector v)
                        SquareMatrix W;
                        SquareMatrix R;
                        Matrix T;
                        calculateMatrices(v, out W, out R, out T);  // this converts the 9-dim vector into scale, rotation, transform matrices
                        double lsr = 0.0;
                        if (true)
                                for (int i = 0; i < m_input.Length; i++) // this iterates over all points that exist in both coordinate systems
                                        Point3D result = calculateResult(i, W, R, T); // this calculates an expected transformation from one coordinate system to another
                                        lsr += calculateDifference(i, result); // this is done to calculate the distance between measured and calculated locations, this distance (squared) is what we want to minimize/optimize
                                return lsr;