VGM
Version 5.5
Toggle main menu visibility
Loading...
Searching...
No Matches
packages
RootGM
source
common
transform.cxx
Go to the documentation of this file.
1
// $Id$
2
3
// -----------------------------------------------------------------------
4
// The RootGM package of the Virtual Geometry Model
5
// Copyright (C) 2007, Ivana Hrivnacova
6
// All rights reserved.
7
//
8
// For the licensing terms see vgm/LICENSE.
9
// Contact: ivana@ipno.in2p3.fr
10
// -----------------------------------------------------------------------
11
12
//
13
// RootGM utilities
14
// --------------
15
// Utility functions
16
//
17
// Author: Ivana Hrivnacova; IPN Orsay
18
19
#include "
BaseVGM/common/utilities.h
"
20
21
#include "
RootGM/common/Units.h
"
22
#include "
RootGM/common/transform.h
"
23
24
#include "TGeoBBox.h"
25
#include "TGeoBoolNode.h"
26
#include "TGeoCompositeShape.h"
27
#include "TGeoPatternFinder.h"
28
#include "TMath.h"
29
30
#include <float.h>
31
#include <iostream>
32
#include <math.h>
33
34
//
35
// Root -> VGM
36
//
37
38
//_____________________________________________________________________________
39
VGM::Transform
RootGM::Transform
(
const
TGeoMatrix& matrix)
40
{
41
//
42
// Translation
43
//
44
const
Double_t* translation = matrix.GetTranslation();
45
46
VGM::Transform
transform(
VGM::kSize
);
47
transform[0] = translation[
VGM::kDx
] *
Units::Length
();
48
transform[1] = translation[
VGM::kDy
] *
Units::Length
();
49
transform[2] = translation[
VGM::kDz
] *
Units::Length
();
50
51
// Rotation
52
//
53
const
Double_t* rm = matrix.GetRotationMatrix();
54
55
double
xx, xz,
// 3x3 Rotation Matrix (xy not used)
56
yx, yy, yz, zx, zy, zz;
57
58
xx = rm[0];
59
xz = rm[2];
60
yx = rm[3];
61
yy = rm[4];
62
yz = rm[5];
63
zx = rm[6];
64
zy = rm[7];
65
zz = rm[8];
66
67
// Decompose reflectionZ from rotation matrix
68
69
if
(
HasReflection
(matrix)) {
70
xz = -xz;
71
yz = -yz;
72
zz = -zz;
73
}
74
75
// Get axis angles
76
// (Using E.Tchernaiev formula)
77
78
double
angleX;
79
double
angleY;
80
double
angleZ;
81
double
cosb = sqrt(xx * xx + yx * yx);
82
if
(cosb > 16 * FLT_EPSILON) {
83
angleX = atan2(zy, zz);
84
angleY = atan2(-zx, cosb);
85
angleZ = atan2(yx, xx);
86
}
87
else
{
88
angleX = atan2(-yz, yy);
89
angleY = atan2(-zx, cosb);
90
angleZ = 0.;
91
}
92
93
transform[
VGM::kAngleX
] = angleX * TMath::RadToDeg() *
Units::Angle
();
94
transform[
VGM::kAngleY
] = angleY * TMath::RadToDeg() *
Units::Angle
();
95
transform[
VGM::kAngleZ
] = angleZ * TMath::RadToDeg() *
Units::Angle
();
96
97
// Reflection
98
//
99
transform[
VGM::kReflZ
] = 0.;
100
if
(matrix.IsReflection()) transform[
VGM::kReflZ
] = 1.;
101
102
return
transform;
103
}
104
105
//_____________________________________________________________________________
106
VGM::Transform
RootGM::TransformScale
(
const
TGeoScale& scale)
107
{
108
const
Double_t* dscale = scale.GetScale();
109
110
VGM::Transform
transform(
VGM::kSize
);
111
transform[
VGM::kDx
] = dscale[0];
112
transform[
VGM::kDy
] = dscale[1];
113
transform[
VGM::kDz
] = dscale[2];
114
115
return
transform;
116
}
117
118
//_____________________________________________________________________________
119
bool
RootGM::HasReflection
(
const
TGeoMatrix& matrix)
120
{
121
//
122
/*
123
// Decompose general matrix
124
const Double_t* rm = matrix.GetRotation()
125
126
// Matrix
127
// rm[0] * sm[0], rm[1] * sm[1], rm[2] * sm[2], tm[0]
128
// rm[3] * sm[0], rm[4] * sm[1], rm[5] * sm[2], tm[1]
129
// rm[6] * sm[0], rm[7] * sm[1], rm[8] * sm[2], tm[2]
130
131
double xx, xy, xz, dx, // 4x3 Transformation Matrix
132
yx, yy, yz, dy,
133
zx, zy, zz, dz;
134
135
xx = rm[0]; xy = rm[1]; xz = rm[2];
136
yx = rm[3]; yy = rm[4]; yz = rm[5];
137
zx = rm[6]; zy = rm[7]; zz = rm[8];
138
dx = tm[0]; dy = tm[1]; dz = tm[2];
139
sx = sm[0]; sy = sm[1]; sz = sm[2];
140
141
// If reflection, apply it to scaleZ
142
if (xx*(yy*zz-yz*zy) - xy*(yx*zz-yz*zx) + xz*(yx*zy-yy*zx) < 0)
143
return true;
144
else
145
return false
146
*/
147
148
return
matrix.IsReflection();
149
}
150
151
//
152
// VGM -> Root
153
//
154
155
//_____________________________________________________________________________
156
TGeoMatrix*
RootGM::CreateTransform
(
const
VGM::Transform
& transform)
157
{
158
159
if
(transform.size() !=
VGM::kSize
) {
160
std::cerr <<
"RootGM::CreateTransform: "
<< std::endl;
161
std::cerr <<
"Wrong transform vector size. "
<< std::endl;
162
exit(1);
163
}
164
165
TGeoRotation* rootRotation =
new
TGeoRotation();
166
rootRotation->RotateX(transform[
VGM::kAngleX
] /
Units::Angle
());
167
rootRotation->RotateY(transform[
VGM::kAngleY
] /
Units::Angle
());
168
rootRotation->RotateZ(transform[
VGM::kAngleZ
] /
Units::Angle
());
169
170
if
(
HasReflection
(transform)) {
171
// copy matrix in a new one
172
const
Double_t* matrix = rootRotation->GetRotationMatrix();
173
Double_t matrix2[9];
174
for
(Int_t i = 0; i < 9; i++) matrix2[i] = matrix[i];
175
176
// apply reflectionZ to rotation matrix
177
matrix2[2] = -matrix2[2];
// xz
178
matrix2[5] = -matrix2[5];
// yz
179
matrix2[8] = -matrix2[8];
// zz
180
181
// reset matrix
182
rootRotation->SetMatrix(matrix2);
183
}
184
185
return
new
TGeoCombiTrans(transform[
VGM::kDx
] /
Units::Length
(),
186
transform[
VGM::kDy
] /
Units::Length
(),
187
transform[
VGM::kDz
] /
Units::Length
(), rootRotation);
188
}
189
190
//_____________________________________________________________________________
191
TGeoScale*
RootGM::CreateScale
(
const
VGM::Transform
& transform)
192
{
193
return
new
TGeoScale(
194
transform[
VGM::kDx
], transform[
VGM::kDy
], transform[
VGM::kDz
]);
195
}
196
197
//_____________________________________________________________________________
198
bool
RootGM::HasReflection
(
const
VGM::Transform
& transform)
199
{
200
return
BaseVGM::Round
(transform[
VGM::kReflZ
]) == 1.;
201
}
202
203
//
204
// Root special
205
//
206
207
//_____________________________________________________________________________
208
TGeoHMatrix
RootGM::CompositeLeftTransform
(TGeoShape* shape)
209
{
210
// Returns the transformation of the first constituent of a composite shape,
211
// accumulated over nested composites.
212
// A Root composite solid is defined in the frame in which its constituent
213
// matrices are given, its VGM counterpart in the frame of the first
214
// constituent; this matrix is what separates the two frames.
215
// ---
216
217
TGeoHMatrix total;
218
while
(shape && shape->IsComposite()) {
219
TGeoBoolNode* boolNode = ((TGeoCompositeShape*)shape)->GetBoolNode();
220
if
(!boolNode)
break
;
221
total = total * TGeoHMatrix(*boolNode->GetLeftMatrix());
222
shape = boolNode->GetLeftShape();
223
}
224
return
total;
225
}
226
227
//_____________________________________________________________________________
228
TGeoHMatrix
RootGM::Displacement
(TGeoShape* shape)
229
{
230
TGeoBBox* box =
dynamic_cast<
TGeoBBox*
>
(shape);
231
if
(!box)
return
TGeoHMatrix();
232
233
const
Double_t* origin = box->GetOrigin();
234
if
(!origin)
return
TGeoHMatrix();
235
236
return
TGeoHMatrix(TGeoTranslation(origin[0], origin[1], origin[2]));
237
;
238
}
239
240
//_____________________________________________________________________________
241
242
// The following code was taken from the paper:
243
// http://jgt.akpeters.com/papers/MollerHughes99/
244
// Changed float to double.
245
// See below the authors.
246
247
#include <math.h>
248
249
#define EPSILON 0.000001
250
251
#define CROSS(dest, v1, v2) \
252
{ \
253
dest[0] = v1[1] * v2[2] - v1[2] * v2[1]; \
254
dest[1] = v1[2] * v2[0] - v1[0] * v2[2]; \
255
dest[2] = v1[0] * v2[1] - v1[1] * v2[0]; \
256
}
257
258
#define DOT(v1, v2) (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2])
259
260
#define SUB(dest, v1, v2) \
261
{ \
262
dest[0] = v1[0] - v2[0]; \
263
dest[1] = v1[1] - v2[1]; \
264
dest[2] = v1[2] - v2[2]; \
265
}
266
267
/*
268
* A function for creating a rotation matrix that rotates a vector called
269
* "from" into another vector called "to".
270
* Input : from[3], to[3] which both must be *normalized* non-zero vectors
271
* Output: mtx[3][3] -- a 3x3 matrix in colum-major form
272
* Authors: Tomas Möller, John Hughes
273
* "Efficiently Building a Matrix to Rotate One Vector to Another"
274
* Journal of Graphics Tools, 4(4):1-4, 1999
275
*/
276
void
RootGM::fromToRotation
(
double
from[3],
double
to[3],
double
mtx[3][3])
277
{
278
double
v[3];
279
double
e, h, f;
280
281
CROSS
(v, from, to);
282
e =
DOT
(from, to);
283
f = (e < 0) ? -e : e;
284
if
(f > 1.0 -
EPSILON
)
/* "from" and "to"-vector almost parallel */
285
{
286
double
utmp[3], vtmp[3];
/* temporary storage vectors */
287
double
x[3];
/* vector most nearly orthogonal to "from" */
288
double
c1, c2, c3;
/* coefficients for later use */
289
int
i, j;
290
291
x[0] = (from[0] > 0.0) ? from[0] : -from[0];
292
x[1] = (from[1] > 0.0) ? from[1] : -from[1];
293
x[2] = (from[2] > 0.0) ? from[2] : -from[2];
294
295
if
(x[0] < x[1]) {
296
if
(x[0] < x[2]) {
297
x[0] = 1.0;
298
x[1] = x[2] = 0.0;
299
}
300
else
{
301
x[2] = 1.0;
302
x[0] = x[1] = 0.0;
303
}
304
}
305
else
{
306
if
(x[1] < x[2]) {
307
x[1] = 1.0;
308
x[0] = x[2] = 0.0;
309
}
310
else
{
311
x[2] = 1.0;
312
x[0] = x[1] = 0.0;
313
}
314
}
315
316
utmp[0] = x[0] - from[0];
317
utmp[1] = x[1] - from[1];
318
utmp[2] = x[2] - from[2];
319
vtmp[0] = x[0] - to[0];
320
vtmp[1] = x[1] - to[1];
321
vtmp[2] = x[2] - to[2];
322
323
c1 = 2.0 /
DOT
(utmp, utmp);
324
c2 = 2.0 /
DOT
(vtmp, vtmp);
325
c3 = c1 * c2 *
DOT
(utmp, vtmp);
326
327
for
(i = 0; i < 3; i++) {
328
for
(j = 0; j < 3; j++) {
329
mtx[i][j] = -c1 * utmp[i] * utmp[j] - c2 * vtmp[i] * vtmp[j] +
330
c3 * vtmp[i] * utmp[j];
331
}
332
mtx[i][i] += 1.0;
333
}
334
}
335
else
/* the most common case, unless "from"="to", or "from"=-"to" */
336
{
337
#if 0
338
/* unoptimized version - a good compiler will optimize this. */
339
/* h = (1.0 - e)/DOT(v, v); old code */
340
h = 1.0/(1.0 + e);
/* optimization by Gottfried Chen */
341
mtx[0][0] = e + h * v[0] * v[0];
342
mtx[0][1] = h * v[0] * v[1] - v[2];
343
mtx[0][2] = h * v[0] * v[2] + v[1];
344
345
mtx[1][0] = h * v[0] * v[1] + v[2];
346
mtx[1][1] = e + h * v[1] * v[1];
347
mtx[1][2] = h * v[1] * v[2] - v[0];
348
349
mtx[2][0] = h * v[0] * v[2] - v[1];
350
mtx[2][1] = h * v[1] * v[2] + v[0];
351
mtx[2][2] = e + h * v[2] * v[2];
352
#else
353
/* ...otherwise use this hand optimized version (9 mults less) */
354
double
hvx, hvz, hvxy, hvxz, hvyz;
355
/* h = (1.0 - e)/DOT(v, v); old code */
356
h = 1.0 / (1.0 + e);
/* optimization by Gottfried Chen */
357
hvx = h * v[0];
358
hvz = h * v[2];
359
hvxy = hvx * v[1];
360
hvxz = hvx * v[2];
361
hvyz = hvz * v[1];
362
mtx[0][0] = e + hvx * v[0];
363
mtx[0][1] = hvxy - v[2];
364
mtx[0][2] = hvxz + v[1];
365
366
mtx[1][0] = hvxy + v[2];
367
mtx[1][1] = e + h * v[1] * v[1];
368
mtx[1][2] = hvyz - v[0];
369
370
mtx[2][0] = hvxz - v[1];
371
mtx[2][1] = hvyz + v[0];
372
mtx[2][2] = e + hvz * v[2];
373
#endif
374
}
375
}
utilities.h
Units.h
transform.h
EPSILON
#define EPSILON
Definition
transform.cxx:249
CROSS
#define CROSS(dest, v1, v2)
Definition
transform.cxx:251
DOT
#define DOT(v1, v2)
Definition
transform.cxx:258
RootGM::Units::Length
static double Length()
Return Root length unit in VGM units.
Definition
Units.h:84
RootGM::Units::Angle
static double Angle()
Return Root angle unit in VGM units.
Definition
Units.h:85
BaseVGM::Round
double Round(double x)
Round number.
Definition
utilities.cxx:34
RootGM::fromToRotation
void fromToRotation(double from[3], double to[3], double mtx[3][3])
Definition
transform.cxx:276
RootGM::CompositeLeftTransform
TGeoHMatrix CompositeLeftTransform(TGeoShape *shape)
Definition
transform.cxx:208
RootGM::CreateScale
TGeoScale * CreateScale(const VGM::Transform &transform)
Definition
transform.cxx:191
RootGM::CreateTransform
TGeoMatrix * CreateTransform(const VGM::Transform &transform)
Definition
transform.cxx:156
RootGM::Displacement
TGeoHMatrix Displacement(TGeoShape *shape)
Definition
transform.cxx:228
RootGM::Transform
VGM::Transform Transform(const TGeoMatrix &matrix)
Definition
transform.cxx:39
RootGM::HasReflection
bool HasReflection(const TGeoMatrix &matrix)
Definition
transform.cxx:119
RootGM::TransformScale
VGM::Transform TransformScale(const TGeoScale &scale)
Definition
transform.cxx:106
VGM::Transform
std::vector< double > Transform
Definition
Transform.h:40
VGM::kAngleZ
@ kAngleZ
Definition
Transform.h:49
VGM::kDx
@ kDx
Definition
Transform.h:44
VGM::kSize
@ kSize
Definition
Transform.h:51
VGM::kReflZ
@ kReflZ
Definition
Transform.h:50
VGM::kAngleY
@ kAngleY
Definition
Transform.h:48
VGM::kDz
@ kDz
Definition
Transform.h:46
VGM::kAngleX
@ kAngleX
Definition
Transform.h:47
VGM::kDy
@ kDy
Definition
Transform.h:45
Generated on
for VGM by
1.17.0