/// <summary> /// Create common affine transformation. /// </summary> /// <param name="first">First affine transformation.</param> /// <param name="second">Second affine transformation.</param> /// <returns>Common affine transformation.</returns> public static AffineCoorTransformator Create(AffineCoorTransformator first, AffineCoorTransformator second) { var res = new AffineCoorTransformator(); for (int i = 0; i < dim; ++i) { for (int j = 0; j < dim; ++j) { for (int k = 0; k < dim; ++k) { res.matrix[i, j] += first.matrix[i, k] * second.matrix[k, j]; } } for (int k = 0; k < dim; ++k) { res.matrix[i, dim] += first.matrix[i, k] * second.matrix[k, dim]; } res.matrix[i, dim] += first.matrix[i, dim]; } return res; }
/// <summary> /// Create common affine transformation. /// </summary> /// <param name="first">First affine transformation.</param> /// <param name="second">Second affine transformation.</param> /// <returns>Common affine transformation.</returns> public static AffineCoorTransformator Create(AffineCoorTransformator first, AffineCoorTransformator second) { var res = new AffineCoorTransformator(); for (int i = 0; i < dim; ++i) { for (int j = 0; j < dim; ++j) { for (int k = 0; k < dim; ++k) { res.matrix[i, j] += first.matrix[i, k] * second.matrix[k, j]; } } for (int k = 0; k < dim; ++k) { res.matrix[i, dim] += first.matrix[i, k] * second.matrix[k, dim]; } res.matrix[i, dim] += first.matrix[i, dim]; } return(res); }
private void MainForm_Click(object sender, EventArgs e) { Console.Clear(); #region Create source data. for (int i = 0; i < pointsCountForFill; ++i) { this.sourcePoints[i] = new Point3D( this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)), this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)), this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height))); } for (int i = pointsCountForFill; i < pointsCount; ++i) { this.sourcePoints[i] = new Point3D( this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)), this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)), this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height))); } #endregion Create source data. #region Create target data. Matrix3D matrix3D = new Matrix3D(); matrix3D.Translate(new Vector3D(10, 50, 20)); matrix3D.RotateAt(new Quaternion(new Vector3D(2, 9, 1), 20), new Point3D(30, 30, 70)); matrix3D.Translate(new Vector3D(10, 50, 20)); matrix3D.RotateAt(new Quaternion(new Vector3D(1, 3, 5), -5), new Point3D(10, 0, 10)); Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M11, matrix3D.M21, matrix3D.M31, matrix3D.OffsetX); Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M12, matrix3D.M22, matrix3D.M32, matrix3D.OffsetY); Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M13, matrix3D.M23, matrix3D.M33, matrix3D.OffsetZ); for (int i = 0; i < pointsCount; ++i) { this.targetPoints[i] = matrix3D.Transform(this.sourcePoints[i]); } Point3D[] sourcePointsToFill = new Point3D[pointsCountForFill]; Point3D[] targetPointsToFill = new Point3D[pointsCountForFill]; for (int i = 0; i < pointsCountForFill; ++i) { sourcePointsToFill[i] = this.sourcePoints[i]; targetPointsToFill[i] = this.targetPoints[i]; } AffineCoorTransformator ct = new AffineCoorTransformator(); ct.Fill(sourcePointsToFill, targetPointsToFill); double[] matrix = ct.MatrixCopy; int index = 0; for (int i = 0; i < AffineCoorTransformator.dim; ++i) { for (int j = 0; j < AffineCoorTransformator.dimExt; ++j) { Console.Write("{0,30}", matrix[index]); ++index; } Console.WriteLine(); } Console.WriteLine(); #endregion Create target data. double[] error = new double[pointsCount]; double totalError = 0; for (int i = 0; i < pointsCount; ++i) { this.targetPointsRes[i] = ct.Transform(this.sourcePoints[i]); error[i] = (this.targetPointsRes[i] - this.targetPoints[i]).Length; Console.WriteLine("Error {0}: {1}.", i, error[i]); totalError += error[i]; } double totalErrorMax = pointsCount * eps * Math.Sqrt(AffineCoorTransformator.dim); Console.WriteLine(); Console.WriteLine("Max: {0}. Current: {1}. Middle: {2}", totalErrorMax, totalError, totalError / pointsCount); Console.WriteLine(); this.Invalidate(); }