15 #include <jama/jama_svd.h>
17 #include "Constants.h"
18 #include "IException.h"
20 #include "LeastSquares.h"
21 #include "PolynomialBivariate.h"
32 p_x = p_y = p_xp = p_yp = 0.0;
49 p_invmat = invert(p_matrix);
50 p_x = p_y = p_xp = p_yp = 0.0;
63 for(
int i = 0 ; i < ident.dim2() ; i++) {
73 void Affine::Identity() {
74 p_matrix = getIdentity();
75 p_invmat = getIdentity();
92 void Affine::Solve(
const double x[],
const double y[],
93 const double xp[],
const double yp[],
int n) {
101 for(
int i = 0; i < n; i++) {
102 vector<double> coord(2);
120 p_matrix[2][0] = 0.0;
121 p_matrix[2][1] = 0.0;
122 p_matrix[2][2] = 1.0;
125 p_invmat = invert(p_matrix);
134 void Affine::Translate(
double tx,
double ty) {
139 p_matrix = TNT::matmult(trans, p_matrix);
143 p_invmat = TNT::matmult(p_invmat, trans);
151 void Affine::Rotate(
double angle) {
154 double angleRadians = angle *
Isis::PI / 180.0;
155 rot[0][0] = cos(angleRadians);
156 rot[0][1] = -sin(angleRadians);
157 rot[1][0] = sin(angleRadians);
158 rot[1][1] = cos(angleRadians);
159 p_matrix = TNT::matmult(rot, p_matrix);
161 angleRadians = -angleRadians;
162 rot[0][0] = cos(angleRadians);
163 rot[0][1] = -sin(angleRadians);
164 rot[1][0] = sin(angleRadians);
165 rot[1][1] = cos(angleRadians);
166 p_invmat = TNT::matmult(p_invmat, rot);
174 void Affine::Scale(
double scaleFactor) {
176 scale[0][0] = scaleFactor;
177 scale[1][1] = scaleFactor;
178 p_matrix = TNT::matmult(scale, p_matrix);
181 p_invmat = invert(p_matrix);
191 void Affine::Compute(
double x,
double y) {
194 p_xp = p_matrix[0][0] * x + p_matrix[0][1] * y + p_matrix[0][2];
195 p_yp = p_matrix[1][0] * x + p_matrix[1][1] * y + p_matrix[1][2];
205 void Affine::ComputeInverse(
double xp,
double yp) {
208 p_x = p_invmat[0][0] * xp + p_invmat[0][1] * yp + p_invmat[0][2];
209 p_y = p_invmat[1][0] * xp + p_invmat[1][1] * yp + p_invmat[1][2];
220 vector<double> Affine::Coefficients(
int var) {
222 vector <double> coef;
223 coef.push_back(p_matrix[index][0]);
224 coef.push_back(p_matrix[index][1]);
225 coef.push_back(p_matrix[index][2]);
237 vector<double> Affine::InverseCoefficients(
int var) {
239 vector <double> coef;
240 coef.push_back(p_invmat[index][0]);
241 coef.push_back(p_invmat[index][1]);
242 coef.push_back(p_invmat[index][2]);
251 void Affine::checkDims(
const AMatrix &am)
const {
252 if((am.dim1() != 3) && (am.dim2() != 3)) {
254 mess <<
"Affine matrices must be 3x3 - this one is " << am.dim1()
256 throw IException(IException::Programmer, mess.str(), _FILEINFO_);
276 JAMA::SVD<double> svd(a);
284 for(
int i = 0; i < invS.dim1(); i++) {
285 if(invS[i][i] == 0.0) {
286 string msg =
"Affine transform not invertible";
287 throw IException(IException::Unknown, msg, _FILEINFO_);
289 invS[i][i] = 1.0 / invS[i][i];
295 AMatrix transU(U.dim2(), U.dim1());
296 for(
int r = 0; r < U.dim1(); r++) {
297 for(
int c = 0; c < U.dim2(); c++) {
298 transU[c][r] = U[r][c];
303 AMatrix VinvS = TNT::matmult(V, invS);
304 return (TNT::matmult(VinvS, transU));