-
Notifications
You must be signed in to change notification settings - Fork 1
/
Transformation.h
183 lines (138 loc) · 4.32 KB
/
Transformation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#ifndef TRANSFORMATION_H
#define TRANSFORMATION_H
#include <vector>
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/StdVector>
#include "Ray.h"
#define PI 3.14159265
using namespace std;
class Transformation
{
public:
Transformation();
Transformation(const Transformation &rhs);
Transformation& operator=(const Transformation &rhs);
friend ostream& operator<< (ostream &out, Transformation &t);
friend Transformation operator* (const Transformation& x, const Transformation& y);
friend Eigen::Vector4d operator* (const Transformation& x, const Eigen::Vector4d& y);
friend Ray operator* (const Transformation& x, const Ray& y);
friend LocalGeo operator* (const Transformation& x, const LocalGeo& y);
virtual Transformation* getInverse() const;
Transformation* compose(const vector<Transformation*> &ts);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
protected:
Eigen::Matrix4d matrix, inverseTranspose;
};
Transformation::Transformation() {
matrix = Eigen::Matrix4d::Identity();
inverseTranspose = Eigen::Matrix4d::Identity();
}
Transformation::Transformation(const Transformation &rhs) {
matrix = rhs.matrix;
inverseTranspose = rhs.inverseTranspose;
}
Transformation& Transformation::operator=(const Transformation &rhs) {
if (this == &rhs) {
return *this;
}
matrix = rhs.matrix;
inverseTranspose = rhs.inverseTranspose;
return *this;
}
ostream& operator<< (ostream &out, Transformation &t) {
out << "Matrix: " << endl;
out << t.matrix;
out << "Inverse Transpose: " << endl;
out << t.inverseTranspose;
return out;
}
Transformation operator* (const Transformation& x, const Transformation& y) {
Transformation temp;
temp.matrix = x.matrix * y.matrix;
temp.inverseTranspose = x.inverseTranspose * y.inverseTranspose;
return temp;
}
Ray operator* (const Transformation& x, const Ray& y) {
Ray temp = y;
temp.direction = x.matrix * y.direction;
temp.source = x.matrix * y.source;
return temp;
}
LocalGeo operator* (const Transformation& x, const LocalGeo& y) {
LocalGeo temp = y;
if (y.isHit) {
temp.normal = x.inverseTranspose * y.normal;
temp.normal[3] = 0.0;
temp.normal.normalize();
temp.point = x.matrix * y.point;
}
return temp;
}
Eigen::Vector4d operator* (const Transformation& x, const Eigen::Vector4d& y) {
return x.matrix * y;
}
Transformation* Transformation::getInverse() const {
Transformation* temp = new Transformation();
temp->matrix = (this->inverseTranspose).transpose();
temp->inverseTranspose = (this->matrix).transpose();
return temp;
}
Transformation* Transformation::compose(const vector<Transformation*> &ts) {
Transformation* final = new Transformation();
for (unsigned i = 0; i < ts.size(); i++ ) {
*final = *final * *ts[i];
}
return final;
}
class Scaling : public Transformation
{
public:
Scaling(double sx, double sy, double sz);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
Scaling::Scaling(double sx, double sy, double sz) {
matrix << sx, 0.0, 0.0, 0.0,
0.0, sy, 0.0, 0.0,
0.0, 0.0, sz, 0.0,
0.0, 0.0, 0.0, 1.0;
inverseTranspose = matrix.inverse().transpose();
}
class Translation : public Transformation
{
public:
Translation(double tx, double ty, double tz);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
Translation::Translation(double tx, double ty, double tz) {
matrix << 1.0, 0.0, 0.0, tx,
0.0, 1.0, 0.0, ty,
0.0, 0.0, 1.0, tz,
0.0, 0.0, 0.0, 1.0;
inverseTranspose = matrix.inverse().transpose();
}
class Rotation : public Transformation
{
public:
Rotation(double rx, double ry, double rz);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
Rotation::Rotation(double rx, double ry, double rz) {
if(rx==ry && ry==rz && rz==0){
return;
}
Eigen::Vector3f k(rx, ry, rz);
double theta = k.norm();
k.normalize();
Eigen::Matrix4d ux;
ux << 0.0, -k[2], k[1], 0.0,
k[2], 0.0, -k[0], 0.0,
-k[1], k[0], 0.0, 0.0,
0.0, 0.0, 0.0, 1.0;
Eigen::Matrix4d I = Eigen::Matrix4d::Identity();
double angle = theta*PI/180;
matrix = I + ux * sin(angle) + ux * ux * (1 - cos(angle));
matrix(3, 3) = 1.0;
inverseTranspose = matrix.inverse().transpose();
}
#endif