1 // -*- C++ -*-
2
3 /*
4 * Gnome Chemistry Utils
5 * Transform3d.h - Handle 3D transformations in space groups.
6 *
7 * Copyright (C) 2007-2009 by Jean Bréfort
8 *
9 * This file was originally part of the Open Babel project.
10 * For more information, see <http://openbabel.sourceforge.net/>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 3 of the
15 * License, or (at your option) any later version.
16
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 */
22
23 #include "config.h"
24 #include "matrix.h"
25 #include "transform3d.h"
26 #include "vector.h"
27 #include <sstream>
28
29 using namespace std;
30
31 namespace gcu
32 {
33
Transform3d()34 Transform3d::Transform3d ():
35 Matrix (),
36 Vector ()
37 {
38 }
39
Transform3d(Matrix const & m,Vector const & v)40 Transform3d::Transform3d (Matrix const &m, Vector const &v):
41 Matrix (m),
42 Vector (v)
43 {
44 Normalize ();
45 }
46
Transform3d(double s)47 Transform3d::Transform3d (double s):
48 Matrix (s),
49 Vector ()
50 {
51 }
52
Transform3d(Vector row1,Vector row2,Vector row3,Vector translation)53 Transform3d::Transform3d (Vector row1, Vector row2, Vector row3, Vector translation):
54 Matrix (row1, row2, row3),
55 Vector (translation)
56 {
57 Normalize ();
58 }
59
Transform3d(double d[3][3],double t[3])60 Transform3d::Transform3d (double d[3][3], double t[3]):
61 Matrix (d),
62 Vector (t)
63 {
64 Normalize ();
65 }
66
~Transform3d()67 Transform3d::~Transform3d ()
68 {
69 }
70
operator *(Vector const & v) const71 Vector Transform3d::operator* (Vector const &v) const
72 {
73 return *static_cast <Matrix const *> (this) * v + *static_cast <Vector const *> (this);
74 }
75
operator *(Transform3d const & t) const76 Transform3d Transform3d::operator* (Transform3d const &t) const
77 {
78 return Transform3d (*static_cast <Matrix const *> (this) * *static_cast <Matrix const *> (&t), *this * *static_cast <Vector const *> (&t));
79 }
80
81 /*!
82 */
DescribeAsString() const83 string Transform3d::DescribeAsString() const
84 {
85 ostringstream r;
86 int n, i, j;
87 const Matrix *m = static_cast <const Matrix *> (this);
88 const Vector *v = static_cast <const Vector *> (this);
89 bool neg, first;
90 for (i = 0; i < 3; i++) {
91 if (i)
92 r << ",";
93 n = floor ((*v)[i] * 12.0 + 0.1);
94 j = 0;
95 while ((*m)(i, j) == 0.)
96 j++;
97 neg = (*m)(i, j) < 0.;
98 switch (n) {
99 case 2:
100 r << ((neg)? "1/6": "1/6+");
101 break;
102 case 3:
103 r << ((neg)? "1/4": "1/4+");
104 break;
105 case 4:
106 r << ((neg)? "1/3": "1/3+");
107 break;
108 case 6:
109 r << ((neg)? "1/2": "1/2+");
110 break;
111 case 8:
112 r << ((neg)? "2/3": "2/3+");
113 break;
114 case 9:
115 r << ((neg)? "3/4": "3/4+");
116 break;
117 case 10:
118 r << ((neg)? "5/6": "5/6+");
119 break;
120 }
121 first = true;
122 while (j < 3) {
123 if ((*m) (i, j) != 0.) {
124 neg = (*m) (i, j) < 0.;
125 switch (j) {
126 case 0:
127 r << ((neg)? "-x": (first? "x": "+x"));
128 break;
129 case 1:
130 r << ((neg)? "-y": (first? "y": "+y"));
131 break;
132 case 2:
133 r << ((neg)? "-z": (first? "z": "+z"));
134 break;
135 }
136 first = false;
137 }
138 j++;
139 }
140 }
141 return r.str ();
142 }
143
DescribeAsValues() const144 string Transform3d::DescribeAsValues() const
145 {
146 ostringstream oss;
147 const Matrix *m = static_cast <const Matrix *> (this);
148 const Vector *v = static_cast <const Vector *> (this);
149 oss << (*m) (0,0) << " " << (*m) (0,1) << " " << (*m) (0,2) << " " << v->GetX () << " ";
150 oss << (*m) (1,0) << " " << (*m) (1,1) << " " << (*m) (1,2) << " " << v->GetY () << " ";
151 oss << (*m) (2,0) << " " << (*m) (2,1) << " " << (*m) (2,2) << " " << v->GetZ ();
152 return oss.str ();
153 }
154
Normalize()155 void Transform3d::Normalize()
156 {
157 Vector *vv = static_cast <Vector *> (this);
158 vv->GetRefX () -= floor (vv->GetX () + .01); /* .01 should work in all cases in this context */
159 vv->GetRefY () -= floor (vv->GetY () + .01);
160 vv->GetRefZ () -= floor (vv->GetZ () + .01);
161 }
162
163 } // namespace gcu
164