Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REveTrans.cxx
Go to the documentation of this file.
1// @(#)root/eve7:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007, 2018
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <ROOT/REveTrans.hxx>
13#include <ROOT/REveTypes.hxx>
14#include <ROOT/REveUtil.hxx>
15
16#include "TBuffer.h"
17#include "TClass.h"
18#include "TMath.h"
19
20#include <cctype>
21
22#define F00 0
23#define F01 4
24#define F02 8
25#define F03 12
26
27#define F10 1
28#define F11 5
29#define F12 9
30#define F13 13
31
32#define F20 2
33#define F21 6
34#define F22 10
35#define F23 14
36
37#define F30 3
38#define F31 7
39#define F32 11
40#define F33 15
41
42using namespace ROOT::Experimental;
43
44////////////////////////////////////////////////////////////////////////////////
45/// Declare how this transformation is changing; position still comes from the
46/// matrix. Does not stamp the owning element, which must be stamped with
47/// kCBTransBBox for the motion to be streamed.
48
49void REveTrans::SetMotion(const REveVectorD &vel, const REveVectorD &acc, Double_t max_dt)
50{
51 SetMotion(vel, acc, REveVectorD(0, 0, 1), 0., max_dt);
52}
53
54////////////////////////////////////////////////////////////////////////////////
55/// As above, with a spin of `spin_rate` rad/s about `spin_axis`. The axis is
56/// in the local frame, as for RotateLF(), and is normalised here. A spin on a
57/// non-uniformly scaled transformation shears it. t0 is stamped now, not at
58/// stream time, so changes that are held back do not shift the trajectory.
59
60// clang-format off
61void REveTrans::SetMotion(const REveVectorD &vel, const REveVectorD &acc,
62 const REveVectorD &spin_axis, Double_t spin_rate,
63 Double_t max_dt)
64{
65 if (!fDeltaTrans)
66 fDeltaTrans = std::make_unique<REveDeltaTrans>();
67
69 d.fVel = vel;
70 d.fAcc = acc;
71
72 const Double_t al = spin_axis.Mag();
73 if (al > 1e-9) {
74 d.fSpinAxis = spin_axis;
75 d.fSpinAxis *= 1. / al;
76 d.fSpinRate = spin_rate;
77 } else {
78 d.fSpinAxis.Set(0., 0., 1.);
79 d.fSpinRate = 0.;
80 }
81
82 d.fMaxDt = max_dt;
83 d.fMotionT0 = REveUtil::ServerTimeMs();
84}
85// clang-format on
86
87////////////////////////////////////////////////////////////////////////////////
88/// Stop extrapolating: the element holds wherever the matrix puts it.
89
91{
92 fDeltaTrans.reset();
93}
94
95/** \class REveTrans
96\ingroup REve
97REveTrans is a 4x4 transformation matrix for homogeneous coordinates
98stored internally in a column-major order to allow direct usage by
99GL. The element type is Double32_t as statically the floats would
100be precise enough but continuous operations on the matrix must
101retain precision of column vectors.
102
103Cartan angles are stored in fA[1-3] (+z, -y, +x). They are
104recalculated on demand.
105
106Direct element access (first two should be used with care):
107 - operator[i] direct access to elements, i:0->15
108 - CM(i,j) element 4*j + i; i,j:0->3 { CM ~ c-matrix }
109 - operator(i,j) element 4*(j-1) + i - 1 i,j:1->4
110
111Column-vector access:
112USet Get/SetBaseVec(), Get/SetPos() and Arr[XYZT]() methods.
113
114For all methods taking the matrix indices:
1151->X, 2->Y, 3->Z; 4->Position (if applicable). 0 reserved for time.
116
117Shorthands in method-names:
118LF ~ LocalFrame; PF ~ ParentFrame; IP ~ InPlace
119*/
120
121////////////////////////////////////////////////////////////////////////////////
122/// Default constructor.
123
125 TObject(),
126 fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
127 fUseTrans (kTRUE),
128 fEditTrans(kFALSE),
129 fEditRotation(kTRUE),
130 fEditScale(kTRUE)
131{
132 UnitTrans();
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Constructor.
137
139 TObject(),
140 fA1(t.fA1), fA2(t.fA2), fA3(t.fA3), fAsOK(t.fAsOK),
141 fUseTrans (t.fUseTrans),
142 fEditTrans(t.fEditTrans),
143 fEditRotation(kTRUE),
144 fEditScale(kTRUE)
145{
146 SetTrans(t, kFALSE);
147 if (t.fDeltaTrans)
148 fDeltaTrans = std::make_unique<REveDeltaTrans>(*t.fDeltaTrans);
149}
150
151////////////////////////////////////////////////////////////////////////////////
152/// Constructor.
153
155 TObject(),
156 fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
157 fUseTrans (kTRUE),
158 fEditTrans(kFALSE),
159 fEditRotation(kTRUE),
160 fEditScale(kTRUE)
161{
162 SetFromArray(arr);
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Constructor.
167
169 TObject(),
170 fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
171 fUseTrans (kTRUE),
172 fEditTrans(kFALSE),
173 fEditRotation(kTRUE),
174 fEditScale(kTRUE)
175{
176 SetFromArray(arr);
177}
178
179////////////////////////////////////////////////////////////////////////////////
180/// Reset matrix to unity.
181
183{
184 memset(fM, 0, 16*sizeof(Double_t));
185 fM[F00] = fM[F11] = fM[F22] = fM[F33] = 1;
186 fA1 = fA2 = fA3 = 0;
187 fAsOK = kTRUE;
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Reset matrix to zero, only the perspective scaling is set to w
192/// (1 by default).
193
195{
196 memset(fM, 0, 16*sizeof(Double_t));
197 fM[F33] = w;
198 fA1 = fA2 = fA3 = 0;
199 fAsOK = kFALSE;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Reset rotation part of the matrix to unity.
204
206{
207 memset(fM, 0, 12*sizeof(Double_t));
208 fM[F00] = fM[F11] = fM[F22] = 1;
209 fA1 = fA2 = fA3 = 0;
210 fAsOK = kTRUE;
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Set matrix from another,
215
216void REveTrans::SetTrans(const REveTrans& t, Bool_t copyAngles)
217{
218 memcpy(fM, t.fM, sizeof(fM));
219 if (copyAngles && t.fAsOK) {
220 fAsOK = kTRUE;
221 fA1 = t.fA1; fA2 = t.fA2; fA3 = t.fA3;
222 } else {
223 fAsOK = kFALSE;
224 }
225}
226
227////////////////////////////////////////////////////////////////////////////////
228/// Set matrix from Double_t array.
229
231{
232 for(Int_t i=0; i<16; ++i) fM[i] = arr[i];
233 fAsOK = kFALSE;
234}
235
236////////////////////////////////////////////////////////////////////////////////
237/// Set matrix from Float_t array.
238
240{
241 for(Int_t i=0; i<16; ++i) fM[i] = arr[i];
242 fAsOK = kFALSE;
243}
244
245////////////////////////////////////////////////////////////////////////////////
246/// Setup the matrix as an elementary rotation.
247/// Optimized versions of left/right multiplication with an elementary
248/// rotation matrix are implemented in RotatePF/RotateLF.
249/// Expects identity matrix.
250
252{
253 if(i == j) return;
254 REveTrans& t = *this;
255 t(i,i) = t(j,j) = TMath::Cos(f);
256 Double_t s = TMath::Sin(f);
257 t(i,j) = -s; t(j,i) = s;
258 fAsOK = kFALSE;
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// A function for creating a rotation matrix that rotates a vector called
263/// "from" into another vector called "to".
264/// Input : from[3], to[3] which both must be *normalized* non-zero vectors
265/// Output: mtx[3][3] -- a 3x3 matrix in column-major form
266///
267/// Authors: Tomas Möller, John Hughes
268/// "Efficiently Building a Matrix to Rotate One Vector to Another"
269/// Journal of Graphics Tools, 4(4):1-4, 1999
270
272{
273 static const float kFromToEpsilon = 0.000001f;
274
275 ZeroTrans();
276
277 Float_t e, f;
278 e = from.Dot(to);
279 f = (e < 0.0f) ? -e : e;
280
281 if (f > 1.0f - kFromToEpsilon) /* "from" and "to"-vector almost parallel */
282 {
283 REveVector u, v; /* temporary storage vectors */
284 REveVector x; /* vector most nearly orthogonal to "from" */
285 Float_t c1, c2, c3; /* coefficients for later use */
286
287 x.fX = (from.fX > 0.0f) ? from.fX : -from.fX;
288 x.fY = (from.fY > 0.0f) ? from.fY : -from.fY;
289 x.fZ = (from.fZ > 0.0f) ? from.fZ : -from.fZ;
290
291 if (x.fX < x.fY)
292 {
293 if (x.fX < x.fZ) {
294 x.fX = 1.0f; x.fY = x.fZ = 0.0f;
295 } else {
296 x.fZ = 1.0f; x.fX = x.fY = 0.0f;
297 }
298 }
299 else
300 {
301 if (x.fY < x.fZ) {
302 x.fY = 1.0f; x.fX = x.fZ = 0.0f;
303 } else {
304 x.fZ = 1.0f; x.fX = x.fY = 0.0f;
305 }
306 }
307
308 u.Sub(x, from);
309 v.Sub(x, to);
310
311 c1 = 2.0f / u.Mag2();
312 c2 = 2.0f / v.Mag2();
313 c3 = c1 * c2 * u.Dot(v);
314
315 for (int i = 0; i < 3; i++) {
316 for (int j = 0; j < 3; j++) {
317 CM(i, j) = - c1 * u[i] * u[j]
318 - c2 * v[i] * v[j]
319 + c3 * v[i] * u[j];
320 }
321 CM(i, i) += 1.0;
322 }
323 }
324 else /* the most common case, unless "from"="to", or "from"=-"to" */
325 {
326 REveVector v = from.Cross(to);
327
328 Float_t h, hvx, hvz, hvxy, hvxz, hvyz;
329 h = 1.0f/(1.0f + e);
330 hvx = h * v.fX;
331 hvz = h * v.fZ;
332 hvxy = hvx * v.fY;
333 hvxz = hvx * v.fZ;
334 hvyz = hvz * v.fY;
335
336 CM(0, 0) = e + hvx * v.fX;
337 CM(0, 1) = hvxy - v.fZ;
338 CM(0, 2) = hvxz + v.fY;
339
340 CM(1, 0) = hvxy + v.fZ;
341 CM(1, 1) = e + h * v.fY * v.fY;
342 CM(1, 2) = hvyz - v.fX;
343
344 CM(2, 0) = hvxz - v.fY;
345 CM(2, 1) = hvyz + v.fX;
346 CM(2, 2) = e + hvz * v.fZ;
347 }
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Multiply from left: this = t * this.
352
354{
355 Double_t buf[4];
356 Double_t* col = fM;
357 for(int c=0; c<4; ++c, col+=4) {
358 const Double_t* row = t.fM;
359 for(int r=0; r<4; ++r, ++row)
360 buf[r] = row[0]*col[0] + row[4]*col[1] + row[8]*col[2] + row[12]*col[3];
361 col[0] = buf[0]; col[1] = buf[1]; col[2] = buf[2]; col[3] = buf[3];
362 }
363 fAsOK = kFALSE;
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Multiply from right: this = this * t.
368
370{
371 Double_t buf[4];
372 Double_t* row = fM;
373 for(int r=0; r<4; ++r, ++row) {
374 const Double_t* col = t.fM;
375 for(int c=0; c<4; ++c, col+=4)
376 buf[c] = row[0]*col[0] + row[4]*col[1] + row[8]*col[2] + row[12]*col[3];
377 row[0] = buf[0]; row[4] = buf[1]; row[8] = buf[2]; row[12] = buf[3];
378 }
379 fAsOK = kFALSE;
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Copy, multiply from right and return product.
384/// Avoid unless necessary.
385
387{
388 REveTrans b(*this);
389 b.MultRight(t);
390 return b;
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Transpose 3x3 rotation sub-matrix.
395
397{
398 Double_t x;
399 x = fM[F01]; fM[F01] = fM[F10]; fM[F10] = x;
400 x = fM[F02]; fM[F02] = fM[F20]; fM[F20] = x;
401 x = fM[F12]; fM[F12] = fM[F21]; fM[F21] = x;
402 fAsOK = kFALSE;
403}
404
405////////////////////////////////////////////////////////////////////////////////
406/// Move in local-frame along axis with index ai.
407
409{
410 const Double_t *col = fM + 4*--ai;
411 fM[F03] += amount*col[0]; fM[F13] += amount*col[1]; fM[F23] += amount*col[2];
412}
413
414////////////////////////////////////////////////////////////////////////////////
415/// General move in local-frame.
416
418{
419 fM[F03] += x*fM[0] + y*fM[4] + z*fM[8];
420 fM[F13] += x*fM[1] + y*fM[5] + z*fM[9];
421 fM[F23] += x*fM[2] + y*fM[6] + z*fM[10];
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Rotate in local frame. Does optimised version of MultRight.
426
428{
429 if(i1 == i2) return;
430 // Algorithm: REveTrans a; a.SetupRotation(i1, i2, amount); MultRight(a);
431 // Optimized version:
432 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
433 Double_t b1, b2;
434 Double_t* row = fM;
435 --i1 <<= 2; --i2 <<= 2; // column major
436 for (int r=0; r<4; ++r, ++row) {
437 b1 = cos*row[i1] + sin*row[i2];
438 b2 = cos*row[i2] - sin*row[i1];
439 row[i1] = b1; row[i2] = b2;
440 }
441 fAsOK = kFALSE;
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Move in parent-frame along axis index ai.
446
448{
449 fM[F03 + --ai] += amount;
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// General move in parent-frame.
454
456{
457 fM[F03] += x;
458 fM[F13] += y;
459 fM[F23] += z;
460}
461
462////////////////////////////////////////////////////////////////////////////////
463/// Rotate in parent frame. Does optimised version of MultLeft.
464
466{
467 if(i1 == i2) return;
468 // Algorithm: REveTrans a; a.SetupRotation(i1, i2, amount); MultLeft(a);
469
470 // Optimized version:
471 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
472 Double_t b1, b2;
473 Double_t* col = fM;
474 --i1; --i2;
475 for(int c=0; c<4; ++c, col+=4) {
476 b1 = cos*col[i1] - sin*col[i2];
477 b2 = cos*col[i2] + sin*col[i1];
478 col[i1] = b1; col[i2] = b2;
479 }
480 fAsOK = kFALSE;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Move in a's coord-system along axis-index ai.
485
486void REveTrans::Move(const REveTrans& a, Int_t ai, Double_t amount)
487{
488 const Double_t* vec = a.fM + 4*--ai;
489 fM[F03] += amount*vec[0];
490 fM[F13] += amount*vec[1];
491 fM[F23] += amount*vec[2];
492}
493
494////////////////////////////////////////////////////////////////////////////////
495/// General move in a's coord-system.
496
498{
499 const Double_t* m = a.fM;
500 fM[F03] += x*m[F00] + y*m[F01] + z*m[F02];
501 fM[F13] += x*m[F10] + y*m[F11] + z*m[F12];
502 fM[F23] += x*m[F20] + y*m[F21] + z*m[F22];
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Rotate in a's coord-system, rotating base vector with index i1
507/// into i2.
508
509void REveTrans::Rotate(const REveTrans& a, Int_t i1, Int_t i2, Double_t amount)
510{
511 if(i1 == i2) return;
512 REveTrans x(a);
513 x.Invert();
514 MultLeft(x);
515 RotatePF(i1, i2, amount);
516 MultLeft(a);
517 fAsOK = kFALSE;
518}
519
520////////////////////////////////////////////////////////////////////////////////
521/// Set base-vector with index b.
522
524{
525 Double_t* col = fM + 4*--b;
526 col[0] = x; col[1] = y; col[2] = z;
527 fAsOK = kFALSE;
528}
529
530////////////////////////////////////////////////////////////////////////////////
531/// Set base-vector with index b.
532
534{
535 Double_t* col = fM + 4*--b;
536 v.GetXYZ(col);
537 fAsOK = kFALSE;
538}
539
540////////////////////////////////////////////////////////////////////////////////
541/// Get base-vector with index b.
542
544{
545 return TVector3(&fM[4*--b]);
546}
547
549{
550 // Get base-vector with index b.
551
552 const Double_t* col = fM + 4*--b;
553 v.SetXYZ(col[0], col[1], col[2]);
554}
555
556////////////////////////////////////////////////////////////////////////////////
557/// Set position (base-vec 4).
558
560{
561 fM[F03] = x; fM[F13] = y; fM[F23] = z;
562}
563
565{
566 // Set position (base-vec 4).
567 fM[F03] = x[0]; fM[F13] = x[1]; fM[F23] = x[2];
568}
569
571{
572 // Set position (base-vec 4).
573 fM[F03] = x[0]; fM[F13] = x[1]; fM[F23] = x[2];
574}
575
577{
578 // Set position (base-vec 4).
579 const Double_t* m = t.fM;
580 fM[F03] = m[F03]; fM[F13] = m[F13]; fM[F23] = m[F23];
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Get position (base-vec 4).
585
587{
588 x = fM[F03]; y = fM[F13]; z = fM[F23];
589}
590
592{
593 // Get position (base-vec 4).
594 x[0] = fM[F03]; x[1] = fM[F13]; x[2] = fM[F23];
595}
596
598{
599 // Get position (base-vec 4).
600 x[0] = fM[F03]; x[1] = fM[F13]; x[2] = fM[F23];
601}
602
604{
605 // Get position (base-vec 4).
606 v.SetXYZ(fM[F03], fM[F13], fM[F23]);
607}
608
610{
611 // Get position (base-vec 4).
612 return TVector3(fM[F03], fM[F13], fM[F23]);
613}
614
615namespace
616{
617inline void clamp_angle(Float_t& a)
618{
619 while(a < -TMath::TwoPi()) a += TMath::TwoPi();
620 while(a > TMath::TwoPi()) a -= TMath::TwoPi();
621}
622}
623
625{
626 // Sets Rotation part as given by angles:
627 // a1 around z, -a2 around y, a3 around x.
628
629 clamp_angle(a1); clamp_angle(a2); clamp_angle(a3);
630
631 Double_t a, b, c, d, e, f;
632 a = TMath::Cos(a3); b = TMath::Sin(a3);
633 c = TMath::Cos(a2); d = TMath::Sin(a2); // should be -sin(a2) for positive direction
634 e = TMath::Cos(a1); f = TMath::Sin(a1);
635 Double_t ad = a*d, bd = b*d;
636
637 fM[F00] = c*e; fM[F01] = -bd*e - a*f; fM[F02] = -ad*e + b*f;
638 fM[F10] = c*f; fM[F11] = -bd*f + a*e; fM[F12] = -ad*f - b*e;
639 fM[F20] = d; fM[F21] = b*c; fM[F22] = a*c;
640
641 fA1 = a1; fA2 = a2; fA3 = a3;
642 fAsOK = kTRUE;
643}
644
645////////////////////////////////////////////////////////////////////////////////
646/// Sets Rotation part as given by angles a1, a1, a3 and pattern pat.
647/// Pattern consists of "XxYyZz" characters.
648/// eg: x means rotate about x axis, X means rotate in negative direction
649/// xYz -> R_x(a3) * R_y(-a2) * R_z(a1); (standard Gled representation)
650/// Note that angles and pattern elements have inverted order!
651///
652/// Implements Eulerian/Cardanian angles in a uniform way.
653
655 const char* pat)
656{
657 int n = strspn(pat, "XxYyZz"); if(n > 3) n = 3;
658 // Build Trans ... assign ...
659 Float_t a[] = { a3, a2, a1 };
660 UnitRot();
661 for(int i=0; i<n; i++) {
662 if(isupper(pat[i])) a[i] = -a[i];
663 switch(pat[i]) {
664 case 'x': case 'X': RotateLF(2, 3, a[i]); break;
665 case 'y': case 'Y': RotateLF(3, 1, a[i]); break;
666 case 'z': case 'Z': RotateLF(1, 2, a[i]); break;
667 }
668 }
669 fAsOK = kFALSE;
670}
671
672////////////////////////////////////////////////////////////////////////////////
673/// Get Cardan rotation angles (pattern xYz above).
674
676{
677 if(!fAsOK) {
678 Double_t sx, sy, sz;
679 GetScale(sx, sy, sz);
680 Double_t d = fM[F20]/sx;
681 if(d>1) d=1; else if(d<-1) d=-1; // Fix numerical errors
682 fA2 = TMath::ASin(d);
683 Double_t cos = TMath::Cos(fA2);
684 if(TMath::Abs(cos) > 8.7e-6) {
685 fA1 = TMath::ATan2(fM[F10], fM[F00]);
686 fA3 = TMath::ATan2(fM[F21]/sy, fM[F22]/sz);
687 } else {
688 fA1 = TMath::ATan2(fM[F10]/sx, fM[F11]/sy);
689 fA3 = 0;
690 }
691 fAsOK = kTRUE;
692 }
693 x[0] = fA1; x[1] = fA2; x[2] = fA3;
694}
695
696////////////////////////////////////////////////////////////////////////////////
697/// Scale matrix. Translation part untouched.
698
700{
701 fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
702 fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
703 fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Remove scaling, make all base vectors of unit length.
708
710{
711 Double_t sx, sy, sz;
712 Unscale(sx, sy, sz);
713 return (sx + sy + sz)/3;
714}
715
716////////////////////////////////////////////////////////////////////////////////
717/// Remove scaling, make all base vectors of unit length.
718
720{
721 GetScale(sx, sy, sz);
722 fM[F00] /= sx; fM[F10] /= sx; fM[F20] /= sx;
723 fM[F01] /= sy; fM[F11] /= sy; fM[F21] /= sy;
724 fM[F02] /= sz; fM[F12] /= sz; fM[F22] /= sz;
725}
726
727////////////////////////////////////////////////////////////////////////////////
728/// Deduce scales from sizes of base vectors.
729
731{
732 sx = TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
733 sy = TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
734 sz = TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Set scaling.
739
741{
742 sx /= TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
743 sy /= TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
744 sz /= TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
745
746 fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
747 fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
748 fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Change x scaling.
753
755{
756 sx /= TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
757 fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
758}
759
760////////////////////////////////////////////////////////////////////////////////
761/// Change y scaling.
762
764{
765 sy /= TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
766 fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
767}
768
769////////////////////////////////////////////////////////////////////////////////
770/// Change z scaling.
771
773{
774 sz /= TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
775 fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
776}
777
778////////////////////////////////////////////////////////////////////////////////
779/// Multiply vector in-place.
780
782{
783 v.SetXYZ(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z() + fM[F03]*w,
784 fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z() + fM[F13]*w,
785 fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z() + fM[F23]*w);
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// Multiply vector in-place.
790
792{
793 Double_t r[3] = { v[0], v[1], v[2] };
794 v[0] = fM[F00]*r[0] + fM[F01]*r[1] + fM[F02]*r[2] + fM[F03]*w;
795 v[1] = fM[F10]*r[0] + fM[F11]*r[1] + fM[F12]*r[2] + fM[F13]*w;
796 v[2] = fM[F20]*r[0] + fM[F21]*r[1] + fM[F22]*r[2] + fM[F23]*w;
797}
798
799////////////////////////////////////////////////////////////////////////////////
800/// Multiply vector in-place.
801
803{
804 Double_t r[3] = { v[0], v[1], v[2] };
805 v[0] = fM[F00]*r[0] + fM[F01]*r[1] + fM[F02]*r[2] + fM[F03]*w;
806 v[1] = fM[F10]*r[0] + fM[F11]*r[1] + fM[F12]*r[2] + fM[F13]*w;
807 v[2] = fM[F20]*r[0] + fM[F21]*r[1] + fM[F22]*r[2] + fM[F23]*w;
808}
809
810////////////////////////////////////////////////////////////////////////////////
811/// Multiply vector and return it.
812
814{
815 return TVector3(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z() + fM[F03]*w,
816 fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z() + fM[F13]*w,
817 fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z() + fM[F23]*w);
818}
819
820////////////////////////////////////////////////////////////////////////////////
821/// Multiply vector and fill output array vout.
822
823void REveTrans::Multiply(const Double_t *vin, Double_t* vout, Double_t w) const
824{
825 vout[0] = fM[F00]*vin[0] + fM[F01]*vin[1] + fM[F02]*vin[2] + fM[F03]*w;
826 vout[1] = fM[F10]*vin[0] + fM[F11]*vin[1] + fM[F12]*vin[2] + fM[F13]*w;
827 vout[2] = fM[F20]*vin[0] + fM[F21]*vin[1] + fM[F22]*vin[2] + fM[F23]*w;
828}
829
830////////////////////////////////////////////////////////////////////////////////
831/// Rotate vector in-place. Translation is NOT applied.
832
834{
835 v.SetXYZ(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z(),
836 fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z(),
837 fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z());
838}
839
840////////////////////////////////////////////////////////////////////////////////
841/// Rotate vector in-place. Translation is NOT applied.
842
844{
845 Double_t t[3] = { v[0], v[1], v[2] };
846
847 v[0] = fM[F00]*t[0] + fM[F01]*t[1] + fM[F02]*t[2];
848 v[1] = fM[F10]*t[0] + fM[F11]*t[1] + fM[F12]*t[2];
849 v[2] = fM[F20]*t[0] + fM[F21]*t[1] + fM[F22]*t[2];
850}
851
852////////////////////////////////////////////////////////////////////////////////
853/// Rotate vector in-place. Translation is NOT applied.
854
856{
857 Double_t t[3] = { v[0], v[1], v[2] };
858
859 v[0] = fM[F00]*t[0] + fM[F01]*t[1] + fM[F02]*t[2];
860 v[1] = fM[F10]*t[0] + fM[F11]*t[1] + fM[F12]*t[2];
861 v[2] = fM[F20]*t[0] + fM[F21]*t[1] + fM[F22]*t[2];
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Rotate vector and return the rotated vector. Translation is NOT applied.
866
868{
869 return TVector3(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z(),
870 fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z(),
871 fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z());
872}
873
874////////////////////////////////////////////////////////////////////////////////
875/// Norm 3-vector in column col.
876
878{
879 Double_t* c = fM + 4*--col;
880 const Double_t l = TMath::Sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
881 c[0] /= l; c[1] /= l; c[2] /= l;
882 return l;
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Orto-norm 3-vector in column col with respect to column ref.
887
889{
890 Double_t* c = fM + 4*--col;
891 Double_t* rc = fM + 4*--ref;
892 const Double_t dp = c[0]*rc[0] + c[1]*rc[1] + c[2]*rc[2];
893 c[0] -= rc[0]*dp; c[1] -= rc[1]*dp; c[2] -= rc[2]*dp;
894 return dp;
895}
896
897////////////////////////////////////////////////////////////////////////////////
898/// Orto-norm columns 1 to 3.
899
901{
902 Norm3Column(1);
903 Orto3Column(2,1); Norm3Column(2);
904 fM[F02] = fM[F10]*fM[F21] - fM[F11]*fM[F20];
905 fM[F12] = fM[F20]*fM[F01] - fM[F21]*fM[F00];
906 fM[F22] = fM[F00]*fM[F11] - fM[F01]*fM[F10];
907 // Cross-product faster than the following.
908 // Orto3Column(3,1); Orto3Column(3,2); Norm3Column(3);
909}
910
911////////////////////////////////////////////////////////////////////////////////
912/// Invert matrix.
913/// Copied from ROOT's TMatrixFCramerInv.
914
916{
917 static const REveException eh("REveTrans::Invert ");
918
919 // Find all NECESSARY 2x2 dets: (18 of them)
920 const Double_t det2_12_01 = fM[F10]*fM[F21] - fM[F11]*fM[F20];
921 const Double_t det2_12_02 = fM[F10]*fM[F22] - fM[F12]*fM[F20];
922 const Double_t det2_12_03 = fM[F10]*fM[F23] - fM[F13]*fM[F20];
923 const Double_t det2_12_13 = fM[F11]*fM[F23] - fM[F13]*fM[F21];
924 const Double_t det2_12_23 = fM[F12]*fM[F23] - fM[F13]*fM[F22];
925 const Double_t det2_12_12 = fM[F11]*fM[F22] - fM[F12]*fM[F21];
926 const Double_t det2_13_01 = fM[F10]*fM[F31] - fM[F11]*fM[F30];
927 const Double_t det2_13_02 = fM[F10]*fM[F32] - fM[F12]*fM[F30];
928 const Double_t det2_13_03 = fM[F10]*fM[F33] - fM[F13]*fM[F30];
929 const Double_t det2_13_12 = fM[F11]*fM[F32] - fM[F12]*fM[F31];
930 const Double_t det2_13_13 = fM[F11]*fM[F33] - fM[F13]*fM[F31];
931 const Double_t det2_13_23 = fM[F12]*fM[F33] - fM[F13]*fM[F32];
932 const Double_t det2_23_01 = fM[F20]*fM[F31] - fM[F21]*fM[F30];
933 const Double_t det2_23_02 = fM[F20]*fM[F32] - fM[F22]*fM[F30];
934 const Double_t det2_23_03 = fM[F20]*fM[F33] - fM[F23]*fM[F30];
935 const Double_t det2_23_12 = fM[F21]*fM[F32] - fM[F22]*fM[F31];
936 const Double_t det2_23_13 = fM[F21]*fM[F33] - fM[F23]*fM[F31];
937 const Double_t det2_23_23 = fM[F22]*fM[F33] - fM[F23]*fM[F32];
938
939 // Find all NECESSARY 3x3 dets: (16 of them)
940 const Double_t det3_012_012 = fM[F00]*det2_12_12 - fM[F01]*det2_12_02 + fM[F02]*det2_12_01;
941 const Double_t det3_012_013 = fM[F00]*det2_12_13 - fM[F01]*det2_12_03 + fM[F03]*det2_12_01;
942 const Double_t det3_012_023 = fM[F00]*det2_12_23 - fM[F02]*det2_12_03 + fM[F03]*det2_12_02;
943 const Double_t det3_012_123 = fM[F01]*det2_12_23 - fM[F02]*det2_12_13 + fM[F03]*det2_12_12;
944 const Double_t det3_013_012 = fM[F00]*det2_13_12 - fM[F01]*det2_13_02 + fM[F02]*det2_13_01;
945 const Double_t det3_013_013 = fM[F00]*det2_13_13 - fM[F01]*det2_13_03 + fM[F03]*det2_13_01;
946 const Double_t det3_013_023 = fM[F00]*det2_13_23 - fM[F02]*det2_13_03 + fM[F03]*det2_13_02;
947 const Double_t det3_013_123 = fM[F01]*det2_13_23 - fM[F02]*det2_13_13 + fM[F03]*det2_13_12;
948 const Double_t det3_023_012 = fM[F00]*det2_23_12 - fM[F01]*det2_23_02 + fM[F02]*det2_23_01;
949 const Double_t det3_023_013 = fM[F00]*det2_23_13 - fM[F01]*det2_23_03 + fM[F03]*det2_23_01;
950 const Double_t det3_023_023 = fM[F00]*det2_23_23 - fM[F02]*det2_23_03 + fM[F03]*det2_23_02;
951 const Double_t det3_023_123 = fM[F01]*det2_23_23 - fM[F02]*det2_23_13 + fM[F03]*det2_23_12;
952 const Double_t det3_123_012 = fM[F10]*det2_23_12 - fM[F11]*det2_23_02 + fM[F12]*det2_23_01;
953 const Double_t det3_123_013 = fM[F10]*det2_23_13 - fM[F11]*det2_23_03 + fM[F13]*det2_23_01;
954 const Double_t det3_123_023 = fM[F10]*det2_23_23 - fM[F12]*det2_23_03 + fM[F13]*det2_23_02;
955 const Double_t det3_123_123 = fM[F11]*det2_23_23 - fM[F12]*det2_23_13 + fM[F13]*det2_23_12;
956
957 // Find the 4x4 det:
958 const Double_t det = fM[F00]*det3_123_123 - fM[F01]*det3_123_023 +
959 fM[F02]*det3_123_013 - fM[F03]*det3_123_012;
960
961 if(det == 0) {
962 throw(eh + "matrix is singular.");
963 }
964
965 const Double_t oneOverDet = 1.0/det;
966 const Double_t mn1OverDet = - oneOverDet;
967
968 fM[F00] = det3_123_123 * oneOverDet;
969 fM[F01] = det3_023_123 * mn1OverDet;
970 fM[F02] = det3_013_123 * oneOverDet;
971 fM[F03] = det3_012_123 * mn1OverDet;
972
973 fM[F10] = det3_123_023 * mn1OverDet;
974 fM[F11] = det3_023_023 * oneOverDet;
975 fM[F12] = det3_013_023 * mn1OverDet;
976 fM[F13] = det3_012_023 * oneOverDet;
977
978 fM[F20] = det3_123_013 * oneOverDet;
979 fM[F21] = det3_023_013 * mn1OverDet;
980 fM[F22] = det3_013_013 * oneOverDet;
981 fM[F23] = det3_012_013 * mn1OverDet;
982
983 fM[F30] = det3_123_012 * mn1OverDet;
984 fM[F31] = det3_023_012 * oneOverDet;
985 fM[F32] = det3_013_012 * mn1OverDet;
986 fM[F33] = det3_012_012 * oneOverDet;
987
988 fAsOK = kFALSE;
989 return det;
990}
991
992////////////////////////////////////////////////////////////////////////////////
993/// Stream an object of class REveTrans.
994
996{
997 if (R__b.IsReading()) {
998 REveTrans::Class()->ReadBuffer(R__b, this);
999 fAsOK = kFALSE;
1000 } else {
1001 REveTrans::Class()->WriteBuffer(R__b, this);
1002 }
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006/// Print in reasonable format.
1007
1008void REveTrans::Print(Option_t* /*option*/) const
1009{
1010 const Double_t* row = fM;
1011 for(Int_t i=0; i<4; ++i, ++row)
1012 printf("%8.3f %8.3f %8.3f | %8.3f\n", row[0], row[4], row[8], row[12]);
1013}
1014
1015#include <iomanip>
1016
1017////////////////////////////////////////////////////////////////////////////////
1018/// Print to std::ostream.
1019
1020std::ostream& operator<<(std::ostream& s, const REveTrans& t)
1021{
1022 s.setf(std::ios::fixed, std::ios::floatfield);
1023 s.precision(3);
1024 for(Int_t i=1; i<=4; i++)
1025 for(Int_t j=1; j<=4; j++)
1026 s << t(i,j) << ((j==4) ? "\n" : "\t");
1027 return s;
1028}
1029
1030#include "TGeoMatrix.h"
1031#include "TBuffer3D.h"
1032
1034{
1035 // Initialize from array.
1036
1037 fUseTrans = kTRUE;
1038 memcpy(fM, carr, 16*sizeof(Double_t));
1039 fAsOK = kFALSE;
1040}
1041
1042////////////////////////////////////////////////////////////////////////////////
1043/// Initialize from TGeoMatrix.
1044
1046{
1047 fUseTrans = kTRUE;
1048 const Double_t *r = mat.GetRotationMatrix();
1049 const Double_t *t = mat.GetTranslation();
1050 Double_t *m = fM;
1051 if (mat.IsScale())
1052 {
1053 const Double_t *s = mat.GetScale();
1054 m[0] = r[0]*s[0]; m[1] = r[3]*s[0]; m[2] = r[6]*s[0]; m[3] = 0;
1055 m[4] = r[1]*s[1]; m[5] = r[4]*s[1]; m[6] = r[7]*s[1]; m[7] = 0;
1056 m[8] = r[2]*s[2]; m[9] = r[5]*s[2]; m[10] = r[8]*s[2]; m[11] = 0;
1057 m[12] = t[0]; m[13] = t[1]; m[14] = t[2]; m[15] = 1;
1058 }
1059 else
1060 {
1061 m[0] = r[0]; m[1] = r[3]; m[2] = r[6]; m[3] = 0;
1062 m[4] = r[1]; m[5] = r[4]; m[6] = r[7]; m[7] = 0;
1063 m[8] = r[2]; m[9] = r[5]; m[10] = r[8]; m[11] = 0;
1064 m[12] = t[0]; m[13] = t[1]; m[14] = t[2]; m[15] = 1;
1065 }
1066 fAsOK = kFALSE;
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Set TGeoHMatrix mat.
1071
1073{
1074 Double_t *r = mat.GetRotationMatrix();
1075 Double_t *t = mat.GetTranslation();
1076 Double_t *s = mat.GetScale();
1077 if (fUseTrans)
1078 {
1080 Double_t *m = fM;
1081 GetScale(s[0], s[1], s[2]);
1082 r[0] = m[0]/s[0]; r[3] = m[1]/s[0]; r[6] = m[2]/s[0]; m += 4;
1083 r[1] = m[0]/s[1]; r[4] = m[1]/s[1]; r[7] = m[2]/s[1]; m += 4;
1084 r[2] = m[0]/s[2]; r[5] = m[1]/s[2]; r[8] = m[2]/s[2]; m += 4;
1085 t[0] = m[0]; t[1] = m[1]; t[2] = m[2];
1086 }
1087 else
1088 {
1090 r[0] = 1; r[3] = 0; r[6] = 0;
1091 r[1] = 0; r[4] = 1; r[7] = 0;
1092 r[2] = 0; r[5] = 0; r[8] = 1;
1093 s[0] = s[1] = s[2] = 1;
1094 t[0] = t[1] = t[2] = 0;
1095 }
1096}
1097
1098////////////////////////////////////////////////////////////////////////////////
1099/// Fill transformation part TBuffer3D core section.
1100
1102{
1103 buff.fLocalFrame = fUseTrans;
1104 if (fUseTrans) {
1105 // In phys-shape ctor the rotation part is transposed, due to
1106 // TGeo's convention for rotation matrix. So we have to transpose
1107 // it here, also.
1108 Double_t *m = buff.fLocalMaster;
1109 m[0] = fM[0]; m[1] = fM[4]; m[2] = fM[8]; m[3] = fM[3];
1110 m[4] = fM[1]; m[5] = fM[5]; m[6] = fM[9]; m[7] = fM[7];
1111 m[8] = fM[2]; m[9] = fM[6]; m[10] = fM[10]; m[11] = fM[11];
1112 m[12] = fM[12]; m[13] = fM[13]; m[14] = fM[14]; m[15] = fM[15];
1113 // Otherwise this would do:
1114 // memcpy(buff.fLocalMaster, fM, 16*sizeof(Double_t));
1115 }
1116}
1117
1118////////////////////////////////////////////////////////////////////////////////
1119/// Test if the transformation is a scale.
1120/// To be used by ROOT TGLObject descendants that potentially need to
1121/// use GL_NORMALIZE.
1122/// The low/high limits are expected to be squares of actual limits.
1123///
1124/// Ideally this should be done by the TGLViewer [but is not].
1125
1127{
1128 if (!fUseTrans) return kFALSE;
1129 Double_t s;
1130 s = fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20];
1131 if (s < low || s > high) return kTRUE;
1132 s = fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21];
1133 if (s < low || s > high) return kTRUE;
1134 s = fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22];
1135 if (s < low || s > high) return kTRUE;
1136 return kFALSE;
1137}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
#define F01
Definition TEveTrans.cxx:23
#define F22
Definition TEveTrans.cxx:34
#define F00
Definition TEveTrans.cxx:22
#define F02
Definition TEveTrans.cxx:24
#define F31
Definition TEveTrans.cxx:38
#define F32
Definition TEveTrans.cxx:39
#define F21
Definition TEveTrans.cxx:33
#define F03
Definition TEveTrans.cxx:25
#define F30
Definition TEveTrans.cxx:37
#define F11
Definition TEveTrans.cxx:28
#define F10
Definition TEveTrans.cxx:27
#define F33
Definition TEveTrans.cxx:40
#define F20
Definition TEveTrans.cxx:32
#define F12
Definition TEveTrans.cxx:29
#define F23
Definition TEveTrans.cxx:35
#define F13
Definition TEveTrans.cxx:30
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:42
REveTrans operator*(const REveTrans &t)
Copy, multiply from right and return product.
void UnitRot()
Reset rotation part of the matrix to unity.
void SetBuffer3D(TBuffer3D &buff)
Fill transformation part TBuffer3D core section.
void SetupRotation(Int_t i, Int_t j, Double_t f)
Setup the matrix as an elementary rotation.
Double_t Norm3Column(Int_t col)
Norm 3-vector in column col.
void SetScaleY(Double_t sy)
Change y scaling.
void RotatePF(Int_t i1, Int_t i2, Double_t amount)
Rotate in parent frame. Does optimised version of MultLeft.
Double_t Invert()
Invert matrix.
void MultiplyIP(TVector3 &v, Double_t w=1) const
Multiply vector in-place.
void RotateLF(Int_t i1, Int_t i2, Double_t amount)
Rotate in local frame. Does optimised version of MultRight.
std::unique_ptr< REveDeltaTrans > fDeltaTrans
Streamed motion, null unless set.
Definition REveTrans.hxx:65
void SetMotion(const REveVectorD &vel, const REveVectorD &acc, Double_t max_dt)
Declare how this transformation is changing; position still comes from the matrix.
Definition REveTrans.cxx:49
void GetScale(Double_t &sx, Double_t &sy, Double_t &sz) const
Deduce scales from sizes of base vectors.
REveTrans()
Default constructor.
void TransposeRotationPart()
Transpose 3x3 rotation sub-matrix.
void ZeroTrans(Double_t w=1.0)
Reset matrix to zero, only the perspective scaling is set to w (1 by default).
void Move3PF(Double_t x, Double_t y, Double_t z)
General move in parent-frame.
void SetTrans(const REveTrans &t, Bool_t copyAngles=kTRUE)
Set matrix from another,.
void SetFromArray(const Double_t arr[16])
Set matrix from Double_t array.
void MovePF(Int_t ai, Double_t amount)
Move in parent-frame along axis index ai.
void SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z)
Set base-vector with index b.
void SetScaleX(Double_t sx)
Change x scaling.
void MoveLF(Int_t ai, Double_t amount)
Move in local-frame along axis with index ai.
Double_t Orto3Column(Int_t col, Int_t ref)
Orto-norm 3-vector in column col with respect to column ref.
void SetGeoHMatrix(TGeoHMatrix &mat)
Set TGeoHMatrix mat.
void SetScale(Double_t sx, Double_t sy, Double_t sz)
Set scaling.
void OrtoNorm3()
Orto-norm columns 1 to 3.
void Move(const REveTrans &a, Int_t ai, Double_t amount)
Move in a's coord-system along axis-index ai.
void SetFrom(Double_t *carr)
void Move3LF(Double_t x, Double_t y, Double_t z)
General move in local-frame.
void GetRotAngles(Float_t *x) const
Get Cardan rotation angles (pattern xYz above).
void SetupFromToVec(const REveVector &from, const REveVector &to)
A function for creating a rotation matrix that rotates a vector called "from" into another vector cal...
Double_t CM(Int_t i, Int_t j) const
void Print(Option_t *option="") const override
Print in reasonable format.
TVector3 Multiply(const TVector3 &v, Double_t w=1) const
Multiply vector and return it.
void SetPos(Double_t x, Double_t y, Double_t z)
Set position (base-vec 4).
void Scale(Double_t sx, Double_t sy, Double_t sz)
Scale matrix. Translation part untouched.
void UnitTrans()
Reset matrix to unity.
Bool_t IsScale(Double_t low=0.9, Double_t high=1.1) const
Test if the transformation is a scale.
void Move3(const REveTrans &a, Double_t x, Double_t y, Double_t z)
General move in a's coord-system.
void RotateIP(TVector3 &v) const
Rotate vector in-place. Translation is NOT applied.
void MultRight(const REveTrans &t)
Multiply from right: this = this * t.
void ClearMotion()
Stop extrapolating: the element holds wherever the matrix puts it.
Definition REveTrans.cxx:90
Double_t Unscale()
Remove scaling, make all base vectors of unit length.
void SetScaleZ(Double_t sz)
Change z scaling.
void SetRotByAnyAngles(Float_t a1, Float_t a2, Float_t a3, const char *pat)
Sets Rotation part as given by angles a1, a1, a3 and pattern pat.
void SetRotByAngles(Float_t a1, Float_t a2, Float_t a3)
void MultLeft(const REveTrans &t)
Multiply from left: this = t * this.
TVector3 GetBaseVec(Int_t b) const
Get base-vector with index b.
void Rotate(const REveTrans &a, Int_t i1, Int_t i2, Double_t amount)
Rotate in a's coord-system, rotating base vector with index i1 into i2.
static double ServerTimeMs()
Milliseconds from a monotonic clock, counted from first use.
Definition REveUtil.cxx:42
REveVectorT Cross(const REveVectorT &a) const
REveVectorT & Sub(const REveVectorT &a, const REveVectorT &b)
TT Dot(const REveVectorT &a) const
Generic 3D primitive description class.
Definition TBuffer3D.h:18
Double_t fLocalMaster[16]
Definition TBuffer3D.h:102
Bool_t fLocalFrame
Definition TBuffer3D.h:99
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Bool_t IsReading() const
Definition TBuffer.h:86
Int_t ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
Function called by the Streamer functions to deserialize information from buffer b into object at p.
Definition TClass.cxx:6929
Int_t WriteBuffer(TBuffer &b, void *pointer, const char *info="")
Function called by the Streamer functions to serialize object at p to buffer b.
Definition TClass.cxx:6950
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:459
const Double_t * GetScale() const override
Definition TGeoMatrix.h:530
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:529
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:528
Geometrical transformation package.
Definition TGeoMatrix.h:39
Bool_t IsScale() const
Definition TGeoMatrix.h:68
virtual const Double_t * GetTranslation() const =0
virtual const Double_t * GetScale() const =0
virtual const Double_t * GetRotationMatrix() const =0
Mother of all ROOT objects.
Definition TObject.h:42
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:995
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
void ResetBit(UInt_t f)
Definition TObject.h:203
void SetXYZ(Double_t x, Double_t y, Double_t z)
Definition TVector3.h:230
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
return c2
Definition legend2.C:14
return c3
Definition legend3.C:15
Namespace for ROOT features in testing.
Definition TROOT.h:100
std::ostream & operator<<(std::ostream &s, const REveTrans &t)
REveVectorT< Double_t > REveVectorD
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition TMath.h:637
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:659
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:607
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:601
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
constexpr Double_t TwoPi()
Definition TMath.h:47
How a transformation is changing: the state REveTrans::SetMotion() records.
Definition REveTrans.hxx:32
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4