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