| [0b990d] | 1 | //
 | 
|---|
 | 2 | // matrix3.cc
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
 | 5 | //
 | 
|---|
 | 6 | // Author: Curtis Janssen <cljanss@limitpt.com>
 | 
|---|
 | 7 | // Maintainer: LPS
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // This file is part of the SC Toolkit.
 | 
|---|
 | 10 | //
 | 
|---|
 | 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
 | 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
 | 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
 | 14 | // any later version.
 | 
|---|
 | 15 | //
 | 
|---|
 | 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
 | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
 | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
 | 19 | // GNU Library General Public License for more details.
 | 
|---|
 | 20 | //
 | 
|---|
 | 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
 | 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
 | 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
 | 24 | //
 | 
|---|
 | 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
 | 26 | //
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | #ifdef __GNUC__
 | 
|---|
 | 29 | #pragma implementation
 | 
|---|
 | 30 | #endif
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | #include <iostream>
 | 
|---|
 | 33 | #include <iomanip>
 | 
|---|
 | 34 | #include <math.h>
 | 
|---|
 | 35 | 
 | 
|---|
 | 36 | #include <util/misc/formio.h>
 | 
|---|
 | 37 | #include <math/scmat/matrix3.h>
 | 
|---|
 | 38 | #include <math/scmat/vector3.h>
 | 
|---|
 | 39 | 
 | 
|---|
 | 40 | using namespace std;
 | 
|---|
 | 41 | using namespace sc;
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 | namespace sc {
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 46 | // DMatrix3
 | 
|---|
 | 47 | 
 | 
|---|
 | 48 | // Commented out for debugging symmetry class
 | 
|---|
 | 49 | #if 0
 | 
|---|
 | 50 | SCMatrix3::SCMatrix3(const RefSCMatrix&x)
 | 
|---|
 | 51 | {
 | 
|---|
 | 52 |   if (x.dim().n() != 3) {
 | 
|---|
 | 53 |       ExEnv::errn() << indent "SCMatrix3::SCMatrix3(RefSCMatrix&): bad length\n";
 | 
|---|
 | 54 |       abort();
 | 
|---|
 | 55 |     }
 | 
|---|
 | 56 |   _v[0] = x.get_element(0);
 | 
|---|
 | 57 |   _v[1] = x.get_element(1);
 | 
|---|
 | 58 |   _v[2] = x.get_element(2);
 | 
|---|
 | 59 | };
 | 
|---|
 | 60 | #endif 
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 | SCMatrix3::SCMatrix3(double x[9])
 | 
|---|
 | 63 | {
 | 
|---|
 | 64 |     _m[0] = x[0];
 | 
|---|
 | 65 |     _m[1] = x[1];
 | 
|---|
 | 66 |     _m[2] = x[2];
 | 
|---|
 | 67 |     _m[3] = x[3];
 | 
|---|
 | 68 |     _m[4] = x[4];
 | 
|---|
 | 69 |     _m[5] = x[5];
 | 
|---|
 | 70 |     _m[6] = x[6];
 | 
|---|
 | 71 |     _m[7] = x[7];
 | 
|---|
 | 72 |     _m[8] = x[8];
 | 
|---|
 | 73 | };
 | 
|---|
 | 74 | 
 | 
|---|
 | 75 | SCMatrix3::SCMatrix3(const SCVector3& c0,
 | 
|---|
 | 76 |                      const SCVector3& c1,
 | 
|---|
 | 77 |                      const SCVector3& c2)
 | 
|---|
 | 78 | {
 | 
|---|
 | 79 |     operator()(0,0)=c0[0];
 | 
|---|
 | 80 |     operator()(1,0)=c0[1];
 | 
|---|
 | 81 |     operator()(2,0)=c0[2];
 | 
|---|
 | 82 |     operator()(0,1)=c1[0];
 | 
|---|
 | 83 |     operator()(1,1)=c1[1];
 | 
|---|
 | 84 |     operator()(2,1)=c1[2];
 | 
|---|
 | 85 |     operator()(0,2)=c2[0];
 | 
|---|
 | 86 |     operator()(1,2)=c2[1];
 | 
|---|
 | 87 |     operator()(2,2)=c2[2];
 | 
|---|
 | 88 | };
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 | SCMatrix3::SCMatrix3(const SCMatrix3&p)
 | 
|---|
 | 91 | {
 | 
|---|
 | 92 |     _m[0] = p[0];
 | 
|---|
 | 93 |     _m[1] = p[1];
 | 
|---|
 | 94 |     _m[2] = p[2];
 | 
|---|
 | 95 |     _m[3] = p[3];
 | 
|---|
 | 96 |     _m[4] = p[4];
 | 
|---|
 | 97 |     _m[5] = p[5];
 | 
|---|
 | 98 |     _m[6] = p[6];
 | 
|---|
 | 99 |     _m[7] = p[7];
 | 
|---|
 | 100 |     _m[8] = p[8];
 | 
|---|
 | 101 | };
 | 
|---|
 | 102 | 
 | 
|---|
 | 103 | SCMatrix3& SCMatrix3::operator=(const SCMatrix3&p)
 | 
|---|
 | 104 | {
 | 
|---|
 | 105 |     _m[0] = p[0];
 | 
|---|
 | 106 |     _m[1] = p[1];
 | 
|---|
 | 107 |     _m[2] = p[2];
 | 
|---|
 | 108 |     _m[3] = p[3];
 | 
|---|
 | 109 |     _m[4] = p[4];
 | 
|---|
 | 110 |     _m[5] = p[5];
 | 
|---|
 | 111 |     _m[6] = p[6];
 | 
|---|
 | 112 |     _m[7] = p[7];
 | 
|---|
 | 113 |     _m[8] = p[8];
 | 
|---|
 | 114 | 
 | 
|---|
 | 115 |     return *this;
 | 
|---|
 | 116 | };
 | 
|---|
 | 117 | 
 | 
|---|
 | 118 | // This function builds a rotation matrix that rotates clockwise
 | 
|---|
 | 119 | // around the given axis
 | 
|---|
 | 120 | SCMatrix3 rotation_mat(const SCVector3& inaxis, double theta)
 | 
|---|
 | 121 | {
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 |     // Normalize the rotation axis
 | 
|---|
 | 124 |     SCVector3 axis=inaxis;
 | 
|---|
 | 125 |     axis.normalize();
 | 
|---|
 | 126 |     
 | 
|---|
 | 127 |     // Calculate the e0-e3  (Following formulae in Goldstein's Classical
 | 
|---|
 | 128 |     // Mechanics eqn 4-67
 | 
|---|
 | 129 |     double e0=cos(theta/2.0);
 | 
|---|
 | 130 |     double e1=axis.x()*sin(theta/2.0);
 | 
|---|
 | 131 |     double e2=axis.y()*sin(theta/2.0);
 | 
|---|
 | 132 |     double e3=axis.z()*sin(theta/2.0);
 | 
|---|
 | 133 |     
 | 
|---|
 | 134 |     SCMatrix3 result;
 | 
|---|
 | 135 | 
 | 
|---|
 | 136 |     result(0,0)=e0*e0+e1*e1-e2*e2-e3*e3;
 | 
|---|
 | 137 |     result(1,0)=2.*(e1*e2-e0*e3);
 | 
|---|
 | 138 |     result(2,0)=2.*(e1*e3+e0*e2);
 | 
|---|
 | 139 |     result(0,1)=2.*(e1*e2+e0*e3);
 | 
|---|
 | 140 |     result(1,1)=e0*e0-e1*e1+e2*e2-e3*e3;
 | 
|---|
 | 141 |     result(2,1)=2.*(e2*e3-e0*e1);
 | 
|---|
 | 142 |     result(0,2)=2.*(e1*e3-e0*e2);
 | 
|---|
 | 143 |     result(1,2)=2.*(e2*e3+e0*e1);
 | 
|---|
 | 144 |     result(2,2)=e0*e0-e1*e1-e2*e2+e3*e3;
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 |     return result;
 | 
|---|
 | 147 | }
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 | SCMatrix3 rotation_mat(const SCVector3& v1,  const SCVector3& v2, double theta)
 | 
|---|
 | 150 | {
 | 
|---|
 | 151 |     return rotation_mat(v1.cross(v2), theta);
 | 
|---|
 | 152 | }
 | 
|---|
 | 153 | 
 | 
|---|
 | 154 | // This function builds the rotation matrix that will rotate the vector
 | 
|---|
 | 155 | // ref to the vector target, through an axis that is the cross product
 | 
|---|
 | 156 | // of the two.
 | 
|---|
 | 157 | SCMatrix3 rotation_mat(const SCVector3& ref,  const SCVector3& target)
 | 
|---|
 | 158 | {
 | 
|---|
 | 159 |     return rotation_mat(target.perp_unit(ref),
 | 
|---|
 | 160 |                         acos(ref.dot(target)/(ref.norm()*target.norm())));
 | 
|---|
 | 161 | }
 | 
|---|
 | 162 | 
 | 
|---|
 | 163 | // This function builds a reflection matrix, that reflects the 
 | 
|---|
 | 164 | // coordinates though a plane perpendicular with unit normal n
 | 
|---|
 | 165 | // and intersecting the origin
 | 
|---|
 | 166 | SCMatrix3 reflection_mat(const SCVector3& innormal)
 | 
|---|
 | 167 | {
 | 
|---|
 | 168 |     // Normalize the reflection normal
 | 
|---|
 | 169 |     SCVector3 n = innormal;
 | 
|---|
 | 170 |     n.normalize();
 | 
|---|
 | 171 |     SCMatrix3 result;
 | 
|---|
 | 172 |     
 | 
|---|
 | 173 |     for (int i=0; i<3; i++)
 | 
|---|
 | 174 |         for (int j=0; j<3; j++)
 | 
|---|
 | 175 |             result(i,j)=delta(i,j)-2.0*n[i]*n[j];
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 |     return result;
 | 
|---|
 | 178 | }
 | 
|---|
 | 179 | 
 | 
|---|
 | 180 | SCMatrix3 SCMatrix3::operator*(const SCMatrix3& v) const
 | 
|---|
 | 181 | {
 | 
|---|
 | 182 |   SCMatrix3 result;
 | 
|---|
 | 183 |   for (int i=0; i<3; i++)
 | 
|---|
 | 184 |       for (int j=0; j<3; j++)
 | 
|---|
 | 185 |       {
 | 
|---|
 | 186 |           result(i,j) = 0;
 | 
|---|
 | 187 |           for (int k=0; k<3; k++)
 | 
|---|
 | 188 |               result(i,j)+=operator()(i,k)*v(k,j);
 | 
|---|
 | 189 |       }
 | 
|---|
 | 190 |   return result;
 | 
|---|
 | 191 | }
 | 
|---|
 | 192 | 
 | 
|---|
 | 193 | SCMatrix3
 | 
|---|
 | 194 | operator*(double d, const SCMatrix3& v)
 | 
|---|
 | 195 | {
 | 
|---|
 | 196 |   SCMatrix3 result;
 | 
|---|
 | 197 |   for (int i=0; i<9; i++) result[i] = d * v[i];
 | 
|---|
 | 198 |   return result;
 | 
|---|
 | 199 | }
 | 
|---|
 | 200 | 
 | 
|---|
 | 201 | SCMatrix3 SCMatrix3::operator*(double d) const
 | 
|---|
 | 202 | {
 | 
|---|
 | 203 |   return d*(*this);
 | 
|---|
 | 204 | }
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 | SCMatrix3 SCMatrix3::operator+(const SCMatrix3&v) const
 | 
|---|
 | 207 | {
 | 
|---|
 | 208 |   SCMatrix3 result;
 | 
|---|
 | 209 |   for (int i=0; i<9; i++) result[i] = _m[i] + v[i];
 | 
|---|
 | 210 |   return result;
 | 
|---|
 | 211 | }
 | 
|---|
 | 212 | 
 | 
|---|
 | 213 | SCMatrix3 SCMatrix3::operator-(const SCMatrix3&v) const
 | 
|---|
 | 214 | {
 | 
|---|
 | 215 |   SCMatrix3 result;
 | 
|---|
 | 216 |   for (int i=0; i<9; i++) result[i] = _m[i] - v[i];
 | 
|---|
 | 217 |   return result;
 | 
|---|
 | 218 | }
 | 
|---|
 | 219 | 
 | 
|---|
 | 220 | 
 | 
|---|
 | 221 | void SCMatrix3::print(ostream& os) const
 | 
|---|
 | 222 | {
 | 
|---|
 | 223 |   os << indent << "{"
 | 
|---|
 | 224 |      << setw(8) << setprecision(5) << operator()(0,0) << " "
 | 
|---|
 | 225 |      << setw(8) << setprecision(5) << operator()(0,1) << " "
 | 
|---|
 | 226 |      << setw(8) << setprecision(5) << operator()(0,2) << "}\n";
 | 
|---|
 | 227 |   os << indent << "{"
 | 
|---|
 | 228 |      << setw(8) << setprecision(5) << operator()(1,0) << " "
 | 
|---|
 | 229 |      << setw(8) << setprecision(5) << operator()(1,1) << " "
 | 
|---|
 | 230 |      << setw(8) << setprecision(5) << operator()(1,2) << "}\n";
 | 
|---|
 | 231 |   os << indent << "{"
 | 
|---|
 | 232 |      << setw(8) << setprecision(5) << operator()(2,0) << " "
 | 
|---|
 | 233 |      << setw(8) << setprecision(5) << operator()(2,1) << " "
 | 
|---|
 | 234 |      << setw(8) << setprecision(5) << operator()(2,2) << "}\n";
 | 
|---|
 | 235 | }
 | 
|---|
 | 236 | 
 | 
|---|
 | 237 | }
 | 
|---|
 | 238 | 
 | 
|---|
 | 239 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 240 | 
 | 
|---|
 | 241 | // Local Variables:
 | 
|---|
 | 242 | // mode: c++
 | 
|---|
 | 243 | // c-file-style: "CLJ"
 | 
|---|
 | 244 | // End:
 | 
|---|