00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <archon/math/matrix.H>
00021
00022 namespace Archon
00023 {
00024 namespace Math
00025 {
00026 Matrix3x3 Matrix3x3::makeZero()
00027 {
00028 return Matrix3x3(Vector3::zero(), Vector3::zero(), Vector3::zero());
00029 }
00030
00031 Matrix3x3 Matrix3x3::makeIdentity()
00032 {
00033 return Matrix3x3(Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1));
00034 }
00035
00036 const Matrix3x3 &Matrix3x3::zero()
00037 {
00038 static Matrix3x3 v = makeZero();
00039 return v;
00040 }
00041
00042 const Matrix3x3 &Matrix3x3::identity()
00043 {
00044 static Matrix3x3 v = makeIdentity();
00045 return v;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 void Matrix3x3::setRotation(const Rotation3 &r)
00082 {
00083 const double ca = cos(r.angle);
00084 const double sa = sin(r.angle);
00085
00086 const double cx = (1 - ca) * r.axis[0];
00087 const double cy = (1 - ca) * r.axis[1];
00088 const double cz = (1 - ca) * r.axis[2];
00089
00090 const double cxy = cx * r.axis[1];
00091 const double cyz = cy * r.axis[2];
00092 const double czx = cz * r.axis[0];
00093
00094 const double sx = r.axis[0] * sa;
00095 const double sy = r.axis[1] * sa;
00096 const double sz = r.axis[2] * sa;
00097
00098 x.set(ca + cx * r.axis[0], cxy + sz, czx - sy);
00099 y.set(cxy - sz, ca + cy * r.axis[1], cyz + sx);
00100 z.set(czx + sy, cyz - sx, ca + cz * r.axis[2]);
00101 }
00102
00103 void Matrix3x3::setRotation(const Quaternion &q)
00104 {
00105 double xx = q.v[0] * q.v[0];
00106 double xy = q.v[0] * q.v[1];
00107 double xz = q.v[0] * q.v[2];
00108 double xw = q.v[0] * q.w;
00109
00110 double yy = q.v[1] * q.v[1];
00111 double yz = q.v[1] * q.v[2];
00112 double yw = q.v[1] * q.w;
00113
00114 double zz = q.v[2] * q.v[2];
00115 double zw = q.v[2] * q.w;
00116
00117 x[0] = 1 - 2 * (yy + zz);
00118 y[0] = 2 * (xy - zw);
00119 z[0] = 2 * (xz + yw);
00120
00121 x[1] = 2 * (xy + zw);
00122 y[1] = 1 - 2 * (xx + zz);
00123 z[1] = 2 * (yz - xw);
00124
00125 x[2] = 2 * (xz - yw);
00126 y[2] = 2 * (yz + xw);
00127 z[2] = 1 - 2 * (xx + yy);
00128 }
00129
00130 void Matrix3x3::setInverseOf(const Matrix3x3 &m)
00131 {
00132 x[0] = m.y[1] * m.z[2] - m.z[1] * m.y[2];
00133 y[0] = m.y[2] * m.z[0] - m.y[0] * m.z[2];
00134 z[0] = m.y[0] * m.z[1] - m.y[1] * m.z[0];
00135 x[1] = m.z[1] * m.x[2] - m.x[1] * m.z[2];
00136 y[1] = m.x[0] * m.z[2] - m.x[2] * m.z[0];
00137 z[1] = m.x[1] * m.z[0] - m.x[0] * m.z[1];
00138 x[2] = m.x[1] * m.y[2] - m.x[2] * m.y[1];
00139 y[2] = m.x[2] * m.y[0] - m.x[0] * m.y[2];
00140 z[2] = m.x[0] * m.y[1] - m.y[0] * m.x[1];
00141
00142 operator/=(m.det());
00143 }
00144
00145 std::ostream &operator<<(std::ostream &out, const Matrix3x3 &m)
00146 {
00147 out << m.getRow1() << "\n";
00148 out << m.getRow2() << "\n";
00149 out << m.getRow3() << "\n";
00150 return out;
00151 }
00152
00153 void Matrix3x3::rotate(const Rotation3 &r)
00154 {
00155 operator*=(Matrix3x3(r));
00156 }
00157
00161 void Matrix3x3::pitch(double angle)
00162 {
00163 rotate(Rotation3(Vector3(1, 0, 0), angle));
00164 }
00165
00169 void Matrix3x3::yaw(double angle)
00170 {
00171 rotate(Rotation3(Vector3(0, 1, 0), angle));
00172 }
00173
00177 void Matrix3x3::roll(double angle)
00178 {
00179 rotate(Rotation3(Vector3(0, 0, 1), angle));
00180 }
00181
00190 void Matrix3x3::rotateRightHandedOrthoNormal(const Rotation3 &r)
00191 {
00192 Matrix3x3 m(r); m.map(x); m.map(y); x.normalize(); z = x; z *= y; z.normalize(); y = z; y *= x;
00193 }
00194
00203 void Matrix3x3::pitchRightHandedOrthoNormal(double angle)
00204 {
00205 const Matrix3x3 m(Rotation3(x, angle));
00206 m.map(y);
00207 z = x;
00208 z *= y;
00209 z.normalize();
00210 y = z;
00211 y *= x;
00212 }
00213
00222 void Matrix3x3::yawRightHandedOrthoNormal(double angle)
00223 {
00224 const Matrix3x3 m(Rotation3(y, angle));
00225 m.map(z);
00226 x = y;
00227 x *= z;
00228 x.normalize();
00229 z = x;
00230 z *= y;
00231 }
00232
00241 void Matrix3x3::rollRightHandedOrthoNormal(double angle)
00242 {
00243 const Matrix3x3 m(Rotation3(z, angle));
00244 m.map(x);
00245 y = z;
00246 y *= x;
00247 y.normalize();
00248 x = y;
00249 x *= z;
00250 }
00251 }
00252 }
00253