43 using namespace ROOT::Experimental;
 
   44 namespace REX = ROOT::Experimental;
 
   75 REveTrans::REveTrans() :
 
   77    fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
 
   89 REveTrans::REveTrans(
const REveTrans& t) :
 
   91    fA1(t.fA1), fA2(t.fA2), fA3(t.fA3), fAsOK(t.fAsOK),
 
   92    fUseTrans (t.fUseTrans),
 
   93    fEditTrans(t.fEditTrans),
 
  103 REveTrans::REveTrans(
const Double_t arr[16]) :
 
  105    fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
 
  108    fEditRotation(kTRUE),
 
  117 REveTrans::REveTrans(
const Float_t arr[16]) :
 
  119    fA1(0), fA2(0), fA3(0), fAsOK(kFALSE),
 
  122    fEditRotation(kTRUE),
 
  131 void REveTrans::UnitTrans()
 
  133    memset(fM, 0, 16*
sizeof(Double_t));
 
  134    fM[F00] = fM[F11] = fM[F22] = fM[F33] = 1;
 
  143 void REveTrans::ZeroTrans(Double_t w)
 
  145    memset(fM, 0, 16*
sizeof(Double_t));
 
  154 void REveTrans::UnitRot()
 
  156    memset(fM, 0, 12*
sizeof(Double_t));
 
  157    fM[F00] = fM[F11] = fM[F22] = 1;
 
  165 void REveTrans::SetTrans(
const REveTrans& t, Bool_t copyAngles)
 
  167    memcpy(fM, t.fM, 
sizeof(fM));
 
  168    if (copyAngles && t.fAsOK) {
 
  170       fA1 = t.fA1; fA2 = t.fA2; fA3 = t.fA3;
 
  179 void REveTrans::SetFromArray(
const Double_t arr[16])
 
  181    for(Int_t i=0; i<16; ++i) fM[i] = arr[i];
 
  188 void REveTrans::SetFromArray(
const Float_t arr[16])
 
  190    for(Int_t i=0; i<16; ++i) fM[i] = arr[i];
 
  200 void REveTrans::SetupRotation(Int_t i, Int_t j, Double_t f)
 
  203    REveTrans& t = *
this;
 
  204    t(i,i) = t(j,j) = TMath::Cos(f);
 
  205    Double_t s = TMath::Sin(f);
 
  206    t(i,j) = -s; t(j,i) = s;
 
  220 void REveTrans::SetupFromToVec(
const REveVector& from, 
const REveVector& to)
 
  222    static const float kFromToEpsilon = 0.000001f;
 
  228    f = (e < 0.0f) ? -e : e;
 
  230    if (f > 1.0f - kFromToEpsilon) 
 
  236       x.fX = (from.fX > 0.0f) ? from.fX : -from.fX;
 
  237       x.fY = (from.fY > 0.0f) ? from.fY : -from.fY;
 
  238       x.fZ = (from.fZ > 0.0f) ? from.fZ : -from.fZ;
 
  243             x.fX = 1.0f; x.fY = x.fZ = 0.0f;
 
  245             x.fZ = 1.0f; x.fX = x.fY = 0.0f;
 
  251             x.fY = 1.0f; x.fX = x.fZ = 0.0f;
 
  253             x.fZ = 1.0f; x.fX = x.fY = 0.0f;
 
  260       c1 = 2.0f / u.Mag2();
 
  261       c2 = 2.0f / v.Mag2();
 
  262       c3 = c1 * c2  * u.Dot(v);
 
  264       for (
int i = 0; i < 3; i++) {
 
  265          for (
int j = 0; j < 3; j++) {
 
  266             CM(i, j) =  - c1 * u[i] * u[j]
 
  275       REveVector v = from.Cross(to);
 
  277       Float_t h, hvx, hvz, hvxy, hvxz, hvyz;
 
  285       CM(0, 0) = e + hvx * v.fX;
 
  286       CM(0, 1) = hvxy - v.fZ;
 
  287       CM(0, 2) = hvxz + v.fY;
 
  289       CM(1, 0) = hvxy + v.fZ;
 
  290       CM(1, 1) = e + h * v.fY * v.fY;
 
  291       CM(1, 2) = hvyz - v.fX;
 
  293       CM(2, 0) = hvxz - v.fY;
 
  294       CM(2, 1) = hvyz + v.fX;
 
  295       CM(2, 2) = e + hvz * v.fZ;
 
  302 void REveTrans::MultLeft(
const REveTrans& t)
 
  306    for(
int c=0; c<4; ++c, col+=4) {
 
  307       const Double_t* row = t.fM;
 
  308       for(
int r=0; r<4; ++r, ++row)
 
  309          buf[r] = row[0]*col[0] + row[4]*col[1] + row[8]*col[2] + row[12]*col[3];
 
  310       col[0] = buf[0]; col[1] = buf[1]; col[2] = buf[2]; col[3] = buf[3];
 
  318 void REveTrans::MultRight(
const REveTrans& t)
 
  322    for(
int r=0; r<4; ++r, ++row) {
 
  323       const Double_t* col = t.fM;
 
  324       for(
int c=0; c<4; ++c, col+=4)
 
  325          buf[c] = row[0]*col[0] + row[4]*col[1] + row[8]*col[2] + row[12]*col[3];
 
  326       row[0] = buf[0]; row[4] = buf[1]; row[8] = buf[2]; row[12] = buf[3];
 
  335 REveTrans REveTrans::operator*(
const REveTrans& t)
 
  345 void REveTrans::TransposeRotationPart()
 
  348    x = fM[F01]; fM[F01] = fM[F10]; fM[F10] = x;
 
  349    x = fM[F02]; fM[F02] = fM[F20]; fM[F20] = x;
 
  350    x = fM[F12]; fM[F12] = fM[F21]; fM[F21] = x;
 
  357 void REveTrans::MoveLF(Int_t ai, Double_t amount)
 
  359    const Double_t *col = fM + 4*--ai;
 
  360    fM[F03] += amount*col[0]; fM[F13] += amount*col[1]; fM[F23] += amount*col[2];
 
  366 void REveTrans::Move3LF(Double_t x, Double_t y, Double_t z)
 
  368    fM[F03] += x*fM[0] + y*fM[4] + z*fM[8];
 
  369    fM[F13] += x*fM[1] + y*fM[5] + z*fM[9];
 
  370    fM[F23] += x*fM[2] + y*fM[6] + z*fM[10];
 
  376 void REveTrans::RotateLF(Int_t i1, Int_t i2, Double_t amount)
 
  381    const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
 
  384    --i1 <<= 2; --i2 <<= 2; 
 
  385    for (
int r=0; r<4; ++r, ++row) {
 
  386       b1 = cos*row[i1] + sin*row[i2];
 
  387       b2 = cos*row[i2] - sin*row[i1];
 
  388       row[i1] = b1; row[i2] = b2;
 
  396 void REveTrans::MovePF(Int_t ai, Double_t amount)
 
  398    fM[F03 + --ai] += amount;
 
  404 void REveTrans::Move3PF(Double_t x, Double_t y, Double_t z)
 
  414 void REveTrans::RotatePF(Int_t i1, Int_t i2, Double_t amount)
 
  420    const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
 
  424    for(
int c=0; c<4; ++c, col+=4) {
 
  425       b1 = cos*col[i1] - sin*col[i2];
 
  426       b2 = cos*col[i2] + sin*col[i1];
 
  427       col[i1] = b1; col[i2] = b2;
 
  435 void REveTrans::Move(
const REveTrans& a, Int_t ai, Double_t amount)
 
  437    const Double_t* vec = a.fM + 4*--ai;
 
  438    fM[F03] += amount*vec[0];
 
  439    fM[F13] += amount*vec[1];
 
  440    fM[F23] += amount*vec[2];
 
  446 void REveTrans::Move3(
const REveTrans& a, Double_t x, Double_t y, Double_t z)
 
  448    const Double_t* m = a.fM;
 
  449    fM[F03] += x*m[F00] + y*m[F01] + z*m[F02];
 
  450    fM[F13] += x*m[F10] + y*m[F11] + z*m[F12];
 
  451    fM[F23] += x*m[F20] + y*m[F21] + z*m[F22];
 
  458 void REveTrans::Rotate(
const REveTrans& a, Int_t i1, Int_t i2, Double_t amount)
 
  464    RotatePF(i1, i2, amount);
 
  472 void REveTrans::SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z)
 
  474    Double_t* col = fM + 4*--b;
 
  475    col[0] = x; col[1] = y; col[2] = z;
 
  482 void REveTrans::SetBaseVec(Int_t b, 
const TVector3& v)
 
  484    Double_t* col = fM + 4*--b;
 
  492 TVector3 REveTrans::GetBaseVec(Int_t b)
 const 
  494    return TVector3(&fM[4*--b]);
 
  497 void REveTrans::GetBaseVec(Int_t b, TVector3& v)
 const 
  501    const Double_t* col = fM + 4*--b;
 
  502    v.SetXYZ(col[0], col[1], col[2]);
 
  508 void REveTrans::SetPos(Double_t x, Double_t y, Double_t z)
 
  510    fM[F03] = x; fM[F13] = y; fM[F23] = z;
 
  513 void REveTrans::SetPos(Double_t* x)
 
  516    fM[F03] = x[0]; fM[F13] = x[1]; fM[F23] = x[2];
 
  519 void REveTrans::SetPos(Float_t* x)
 
  522    fM[F03] = x[0]; fM[F13] = x[1]; fM[F23] = x[2];
 
  525 void REveTrans::SetPos(
const REveTrans& t)
 
  528    const Double_t* m = t.fM;
 
  529    fM[F03] = m[F03]; fM[F13] = m[F13]; fM[F23] = m[F23];
 
  535 void REveTrans::GetPos(Double_t& x, Double_t& y, Double_t& z)
 const 
  537    x = fM[F03]; y = fM[F13]; z = fM[F23];
 
  540 void REveTrans::GetPos(Double_t* x)
 const 
  543    x[0] = fM[F03]; x[1] = fM[F13]; x[2] = fM[F23];
 
  546 void REveTrans::GetPos(Float_t* x)
 const 
  549    x[0] = fM[F03]; x[1] = fM[F13]; x[2] = fM[F23];
 
  552 void REveTrans::GetPos(TVector3& v)
 const 
  555    v.SetXYZ(fM[F03], fM[F13], fM[F23]);
 
  558 TVector3 REveTrans::GetPos()
 const 
  561    return TVector3(fM[F03], fM[F13], fM[F23]);
 
  566 inline void clamp_angle(Float_t& a)
 
  568    while(a < -TMath::TwoPi()) a += TMath::TwoPi();
 
  569    while(a >  TMath::TwoPi()) a -= TMath::TwoPi();
 
  573 void REveTrans::SetRotByAngles(Float_t a1, Float_t a2, Float_t a3)
 
  578    clamp_angle(a1); clamp_angle(a2); clamp_angle(a3);
 
  580    Double_t a, b, c, d, e, f;
 
  581    a = TMath::Cos(a3); b = TMath::Sin(a3);
 
  582    c = TMath::Cos(a2); d = TMath::Sin(a2); 
 
  583    e = TMath::Cos(a1); f = TMath::Sin(a1);
 
  584    Double_t ad = a*d, bd = b*d;
 
  586    fM[F00] = c*e; fM[F01] = -bd*e - a*f; fM[F02] = -ad*e + b*f;
 
  587    fM[F10] = c*f; fM[F11] = -bd*f + a*e; fM[F12] = -ad*f - b*e;
 
  588    fM[F20] = d;   fM[F21] =  b*c;        fM[F22] =  a*c;
 
  590    fA1 = a1; fA2 = a2; fA3 = a3;
 
  603 void REveTrans::SetRotByAnyAngles(Float_t a1, Float_t a2, Float_t a3,
 
  606    int n = strspn(pat, 
"XxYyZz"); 
if(n > 3) n = 3;
 
  608    Float_t a[] = { a3, a2, a1 };
 
  610    for(
int i=0; i<n; i++) {
 
  611       if(isupper(pat[i])) a[i] = -a[i];
 
  613          case 'x': 
case 'X': RotateLF(2, 3, a[i]); 
break;
 
  614          case 'y': 
case 'Y': RotateLF(3, 1, a[i]); 
break;
 
  615          case 'z': 
case 'Z': RotateLF(1, 2, a[i]); 
break;
 
  624 void REveTrans::GetRotAngles(Float_t* x)
 const 
  628       GetScale(sx, sy, sz);
 
  629       Double_t d = fM[F20]/sx;
 
  630       if(d>1) d=1; 
else if(d<-1) d=-1; 
 
  631       fA2 = TMath::ASin(d);
 
  632       Double_t cos = TMath::Cos(fA2);
 
  633       if(TMath::Abs(cos) > 8.7e-6) {
 
  634          fA1 = TMath::ATan2(fM[F10], fM[F00]);
 
  635          fA3 = TMath::ATan2(fM[F21]/sy, fM[F22]/sz);
 
  637          fA1 = TMath::ATan2(fM[F10]/sx, fM[F11]/sy);
 
  642    x[0] = fA1; x[1] = fA2; x[2] = fA3;
 
  648 void REveTrans::Scale(Double_t sx, Double_t sy, Double_t sz)
 
  650    fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
 
  651    fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
 
  652    fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
 
  658 Double_t REveTrans::Unscale()
 
  662    return (sx + sy + sz)/3;
 
  668 void REveTrans::Unscale(Double_t& sx, Double_t& sy, Double_t& sz)
 
  670    GetScale(sx, sy, sz);
 
  671    fM[F00] /= sx; fM[F10] /= sx; fM[F20] /= sx;
 
  672    fM[F01] /= sy; fM[F11] /= sy; fM[F21] /= sy;
 
  673    fM[F02] /= sz; fM[F12] /= sz; fM[F22] /= sz;
 
  679 void REveTrans::GetScale(Double_t& sx, Double_t& sy, Double_t& sz)
 const 
  681    sx = TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
 
  682    sy = TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
 
  683    sz = TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
 
  689 void REveTrans::SetScale(Double_t sx, Double_t sy, Double_t sz)
 
  691    sx /= TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
 
  692    sy /= TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
 
  693    sz /= TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
 
  695    fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
 
  696    fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
 
  697    fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
 
  703 void REveTrans::SetScaleX(Double_t sx)
 
  705    sx /= TMath::Sqrt( fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20] );
 
  706    fM[F00] *= sx; fM[F10] *= sx; fM[F20] *= sx;
 
  712 void REveTrans::SetScaleY(Double_t sy)
 
  714    sy /= TMath::Sqrt( fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21] );
 
  715    fM[F01] *= sy; fM[F11] *= sy; fM[F21] *= sy;
 
  721 void REveTrans::SetScaleZ(Double_t sz)
 
  723    sz /= TMath::Sqrt( fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22] );
 
  724    fM[F02] *= sz; fM[F12] *= sz; fM[F22] *= sz;
 
  730 void REveTrans::MultiplyIP(TVector3& v, Double_t w)
 const 
  732    v.SetXYZ(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z() + fM[F03]*w,
 
  733             fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z() + fM[F13]*w,
 
  734             fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z() + fM[F23]*w);
 
  740 void REveTrans::MultiplyIP(Double_t* v, Double_t w)
 const 
  742    Double_t r[3] = { v[0], v[1], v[2] };
 
  743    v[0] = fM[F00]*r[0] + fM[F01]*r[1] + fM[F02]*r[2] + fM[F03]*w;
 
  744    v[1] = fM[F10]*r[0] + fM[F11]*r[1] + fM[F12]*r[2] + fM[F13]*w;
 
  745    v[2] = fM[F20]*r[0] + fM[F21]*r[1] + fM[F22]*r[2] + fM[F23]*w;
 
  751 void REveTrans::MultiplyIP(Float_t* v, Double_t w)
 const 
  753    Double_t r[3] = { v[0], v[1], v[2] };
 
  754    v[0] = fM[F00]*r[0] + fM[F01]*r[1] + fM[F02]*r[2] + fM[F03]*w;
 
  755    v[1] = fM[F10]*r[0] + fM[F11]*r[1] + fM[F12]*r[2] + fM[F13]*w;
 
  756    v[2] = fM[F20]*r[0] + fM[F21]*r[1] + fM[F22]*r[2] + fM[F23]*w;
 
  762 TVector3 REveTrans::Multiply(
const TVector3& v, Double_t w)
 const 
  764    return TVector3(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z() + fM[F03]*w,
 
  765                    fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z() + fM[F13]*w,
 
  766                    fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z() + fM[F23]*w);
 
  772 void REveTrans::Multiply(
const Double_t *vin, Double_t* vout, Double_t w)
 const 
  774    vout[0] = fM[F00]*vin[0] + fM[F01]*vin[1] + fM[F02]*vin[2] + fM[F03]*w;
 
  775    vout[1] = fM[F10]*vin[0] + fM[F11]*vin[1] + fM[F12]*vin[1] + fM[F13]*w;
 
  776    vout[2] = fM[F20]*vin[0] + fM[F21]*vin[1] + fM[F22]*vin[1] + fM[F23]*w;
 
  782 void REveTrans::RotateIP(TVector3& v)
 const 
  784    v.SetXYZ(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z(),
 
  785             fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z(),
 
  786             fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z());
 
  792 void REveTrans::RotateIP(Double_t* v)
 const 
  794    Double_t t[3] = { v[0], v[1], v[2] };
 
  796    v[0] = fM[F00]*t[0] + fM[F01]*t[1] + fM[F02]*t[2];
 
  797    v[1] = fM[F10]*t[0] + fM[F11]*t[1] + fM[F12]*t[2];
 
  798    v[2] = fM[F20]*t[0] + fM[F21]*t[1] + fM[F22]*t[2];
 
  804 void REveTrans::RotateIP(Float_t* v)
 const 
  806    Double_t t[3] = { v[0], v[1], v[2] };
 
  808    v[0] = fM[F00]*t[0] + fM[F01]*t[1] + fM[F02]*t[2];
 
  809    v[1] = fM[F10]*t[0] + fM[F11]*t[1] + fM[F12]*t[2];
 
  810    v[2] = fM[F20]*t[0] + fM[F21]*t[1] + fM[F22]*t[2];
 
  816 TVector3 REveTrans::Rotate(
const TVector3& v)
 const 
  818    return TVector3(fM[F00]*v.x() + fM[F01]*v.y() + fM[F02]*v.z(),
 
  819                    fM[F10]*v.x() + fM[F11]*v.y() + fM[F12]*v.z(),
 
  820                    fM[F20]*v.x() + fM[F21]*v.y() + fM[F22]*v.z());
 
  826 Double_t REveTrans::Norm3Column(Int_t col)
 
  828    Double_t* c = fM + 4*--col;
 
  829    const Double_t  l = TMath::Sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
 
  830    c[0] /= l; c[1] /= l; c[2] /= l;
 
  837 Double_t REveTrans::Orto3Column(Int_t col, Int_t ref)
 
  839    Double_t* c =  fM + 4*--col;
 
  840    Double_t* rc = fM + 4*--ref;
 
  841    const Double_t dp = c[0]*rc[0] + c[1]*rc[1] + c[2]*rc[2];
 
  842    c[0] -= rc[0]*dp; c[1] -= rc[1]*dp; c[2] -= rc[2]*dp;
 
  849 void REveTrans::OrtoNorm3()
 
  852    Orto3Column(2,1); Norm3Column(2);
 
  853    fM[F02] = fM[F10]*fM[F21] - fM[F11]*fM[F20];
 
  854    fM[F12] = fM[F20]*fM[F01] - fM[F21]*fM[F00];
 
  855    fM[F22] = fM[F00]*fM[F11] - fM[F01]*fM[F10];
 
  864 Double_t REveTrans::Invert()
 
  866    static const REveException eh(
"REveTrans::Invert ");
 
  869    const Double_t det2_12_01 = fM[F10]*fM[F21] - fM[F11]*fM[F20];
 
  870    const Double_t det2_12_02 = fM[F10]*fM[F22] - fM[F12]*fM[F20];
 
  871    const Double_t det2_12_03 = fM[F10]*fM[F23] - fM[F13]*fM[F20];
 
  872    const Double_t det2_12_13 = fM[F11]*fM[F23] - fM[F13]*fM[F21];
 
  873    const Double_t det2_12_23 = fM[F12]*fM[F23] - fM[F13]*fM[F22];
 
  874    const Double_t det2_12_12 = fM[F11]*fM[F22] - fM[F12]*fM[F21];
 
  875    const Double_t det2_13_01 = fM[F10]*fM[F31] - fM[F11]*fM[F30];
 
  876    const Double_t det2_13_02 = fM[F10]*fM[F32] - fM[F12]*fM[F30];
 
  877    const Double_t det2_13_03 = fM[F10]*fM[F33] - fM[F13]*fM[F30];
 
  878    const Double_t det2_13_12 = fM[F11]*fM[F32] - fM[F12]*fM[F31];
 
  879    const Double_t det2_13_13 = fM[F11]*fM[F33] - fM[F13]*fM[F31];
 
  880    const Double_t det2_13_23 = fM[F12]*fM[F33] - fM[F13]*fM[F32];
 
  881    const Double_t det2_23_01 = fM[F20]*fM[F31] - fM[F21]*fM[F30];
 
  882    const Double_t det2_23_02 = fM[F20]*fM[F32] - fM[F22]*fM[F30];
 
  883    const Double_t det2_23_03 = fM[F20]*fM[F33] - fM[F23]*fM[F30];
 
  884    const Double_t det2_23_12 = fM[F21]*fM[F32] - fM[F22]*fM[F31];
 
  885    const Double_t det2_23_13 = fM[F21]*fM[F33] - fM[F23]*fM[F31];
 
  886    const Double_t det2_23_23 = fM[F22]*fM[F33] - fM[F23]*fM[F32];
 
  889    const Double_t det3_012_012 = fM[F00]*det2_12_12 - fM[F01]*det2_12_02 + fM[F02]*det2_12_01;
 
  890    const Double_t det3_012_013 = fM[F00]*det2_12_13 - fM[F01]*det2_12_03 + fM[F03]*det2_12_01;
 
  891    const Double_t det3_012_023 = fM[F00]*det2_12_23 - fM[F02]*det2_12_03 + fM[F03]*det2_12_02;
 
  892    const Double_t det3_012_123 = fM[F01]*det2_12_23 - fM[F02]*det2_12_13 + fM[F03]*det2_12_12;
 
  893    const Double_t det3_013_012 = fM[F00]*det2_13_12 - fM[F01]*det2_13_02 + fM[F02]*det2_13_01;
 
  894    const Double_t det3_013_013 = fM[F00]*det2_13_13 - fM[F01]*det2_13_03 + fM[F03]*det2_13_01;
 
  895    const Double_t det3_013_023 = fM[F00]*det2_13_23 - fM[F02]*det2_13_03 + fM[F03]*det2_13_02;
 
  896    const Double_t det3_013_123 = fM[F01]*det2_13_23 - fM[F02]*det2_13_13 + fM[F03]*det2_13_12;
 
  897    const Double_t det3_023_012 = fM[F00]*det2_23_12 - fM[F01]*det2_23_02 + fM[F02]*det2_23_01;
 
  898    const Double_t det3_023_013 = fM[F00]*det2_23_13 - fM[F01]*det2_23_03 + fM[F03]*det2_23_01;
 
  899    const Double_t det3_023_023 = fM[F00]*det2_23_23 - fM[F02]*det2_23_03 + fM[F03]*det2_23_02;
 
  900    const Double_t det3_023_123 = fM[F01]*det2_23_23 - fM[F02]*det2_23_13 + fM[F03]*det2_23_12;
 
  901    const Double_t det3_123_012 = fM[F10]*det2_23_12 - fM[F11]*det2_23_02 + fM[F12]*det2_23_01;
 
  902    const Double_t det3_123_013 = fM[F10]*det2_23_13 - fM[F11]*det2_23_03 + fM[F13]*det2_23_01;
 
  903    const Double_t det3_123_023 = fM[F10]*det2_23_23 - fM[F12]*det2_23_03 + fM[F13]*det2_23_02;
 
  904    const Double_t det3_123_123 = fM[F11]*det2_23_23 - fM[F12]*det2_23_13 + fM[F13]*det2_23_12;
 
  907    const Double_t det = fM[F00]*det3_123_123 - fM[F01]*det3_123_023 +
 
  908       fM[F02]*det3_123_013 - fM[F03]*det3_123_012;
 
  911       throw(eh + 
"matrix is singular.");
 
  914    const Double_t oneOverDet = 1.0/det;
 
  915    const Double_t mn1OverDet = - oneOverDet;
 
  917    fM[F00] = det3_123_123 * oneOverDet;
 
  918    fM[F01] = det3_023_123 * mn1OverDet;
 
  919    fM[F02] = det3_013_123 * oneOverDet;
 
  920    fM[F03] = det3_012_123 * mn1OverDet;
 
  922    fM[F10] = det3_123_023 * mn1OverDet;
 
  923    fM[F11] = det3_023_023 * oneOverDet;
 
  924    fM[F12] = det3_013_023 * mn1OverDet;
 
  925    fM[F13] = det3_012_023 * oneOverDet;
 
  927    fM[F20] = det3_123_013 * oneOverDet;
 
  928    fM[F21] = det3_023_013 * mn1OverDet;
 
  929    fM[F22] = det3_013_013 * oneOverDet;
 
  930    fM[F23] = det3_012_013 * mn1OverDet;
 
  932    fM[F30] = det3_123_012 * mn1OverDet;
 
  933    fM[F31] = det3_023_012 * oneOverDet;
 
  934    fM[F32] = det3_013_012 * mn1OverDet;
 
  935    fM[F33] = det3_012_012 * oneOverDet;
 
  944 void REveTrans::Streamer(TBuffer &R__b)
 
  946    if (R__b.IsReading()) {
 
  947       REveTrans::Class()->ReadBuffer(R__b, 
this);
 
  950       REveTrans::Class()->WriteBuffer(R__b, 
this);
 
  957 void REveTrans::Print(Option_t* )
 const 
  959    const Double_t* row = fM;
 
  960    for(Int_t i=0; i<4; ++i, ++row)
 
  961       printf(
"%8.3f %8.3f %8.3f | %8.3f\n", row[0], row[4], row[8], row[12]);
 
  969 std::ostream& operator<<(std::ostream& s, 
const REveTrans& t)
 
  971    s.setf(std::ios::fixed, std::ios::floatfield);
 
  973    for(Int_t i=1; i<=4; i++)
 
  974       for(Int_t j=1; j<=4; j++)
 
  975          s << t(i,j) << ((j==4) ? 
"\n" : 
"\t");
 
  982 void REveTrans::SetFrom(Double_t* carr)
 
  987    memcpy(fM, carr, 16*
sizeof(Double_t));
 
  994 void REveTrans::SetFrom(
const TGeoMatrix& mat)
 
  997    const Double_t *r = mat.GetRotationMatrix();
 
  998    const Double_t *t = mat.GetTranslation();
 
 1002       const Double_t *s = mat.GetScale();
 
 1003       m[0]  = r[0]*s[0]; m[1]  = r[3]*s[0]; m[2]  = r[6]*s[0]; m[3]  = 0;
 
 1004       m[4]  = r[1]*s[1]; m[5]  = r[4]*s[1]; m[6]  = r[7]*s[1]; m[7]  = 0;
 
 1005       m[8]  = r[2]*s[2]; m[9]  = r[5]*s[2]; m[10] = r[8]*s[2]; m[11] = 0;
 
 1006       m[12] = t[0];      m[13] = t[1];      m[14] = t[2];      m[15] = 1;
 
 1010       m[0]  = r[0];      m[1]  = r[3];      m[2]  = r[6];      m[3]  = 0;
 
 1011       m[4]  = r[1];      m[5]  = r[4];      m[6]  = r[7];      m[7]  = 0;
 
 1012       m[8]  = r[2];      m[9]  = r[5];      m[10] = r[8];      m[11] = 0;
 
 1013       m[12] = t[0];      m[13] = t[1];      m[14] = t[2];      m[15] = 1;
 
 1021 void REveTrans::SetGeoHMatrix(TGeoHMatrix& mat)
 
 1023    Double_t *r = mat.GetRotationMatrix();
 
 1024    Double_t *t = mat.GetTranslation();
 
 1025    Double_t *s = mat.GetScale();
 
 1028       mat.SetBit(TGeoMatrix::kGeoGenTrans);
 
 1030       GetScale(s[0], s[1], s[2]);
 
 1031       r[0] = m[0]/s[0]; r[3] = m[1]/s[0]; r[6] = m[2]/s[0]; m += 4;
 
 1032       r[1] = m[0]/s[1]; r[4] = m[1]/s[1]; r[7] = m[2]/s[1]; m += 4;
 
 1033       r[2] = m[0]/s[2]; r[5] = m[1]/s[2]; r[8] = m[2]/s[2]; m += 4;
 
 1034       t[0] = m[0];      t[1] = m[1];      t[2] = m[2];
 
 1038       mat.ResetBit(TGeoMatrix::kGeoGenTrans);
 
 1039       r[0] = 1; r[3] = 0; r[6] = 0;
 
 1040       r[1] = 0; r[4] = 1; r[7] = 0;
 
 1041       r[2] = 0; r[5] = 0; r[8] = 1;
 
 1042       s[0] = s[1] = s[2] = 1;
 
 1043       t[0] = t[1] = t[2] = 0;
 
 1050 void REveTrans::SetBuffer3D(TBuffer3D& buff)
 
 1052    buff.fLocalFrame = fUseTrans;
 
 1057       Double_t *m = buff.fLocalMaster;
 
 1058       m[0]  = fM[0];  m[1]  = fM[4];  m[2]  = fM[8];  m[3]  = fM[3];
 
 1059       m[4]  = fM[1];  m[5]  = fM[5];  m[6]  = fM[9];  m[7]  = fM[7];
 
 1060       m[8]  = fM[2];  m[9]  = fM[6];  m[10] = fM[10]; m[11] = fM[11];
 
 1061       m[12] = fM[12]; m[13] = fM[13]; m[14] = fM[14]; m[15] = fM[15];
 
 1075 Bool_t REveTrans::IsScale(Double_t low, Double_t high)
 const 
 1077    if (!fUseTrans) 
return kFALSE;
 
 1079    s = fM[F00]*fM[F00] + fM[F10]*fM[F10] + fM[F20]*fM[F20];
 
 1080    if (s < low || s > high) 
return kTRUE;
 
 1081    s = fM[F01]*fM[F01] + fM[F11]*fM[F11] + fM[F21]*fM[F21];
 
 1082    if (s < low || s > high) 
return kTRUE;
 
 1083    s = fM[F02]*fM[F02] + fM[F12]*fM[F12] + fM[F22]*fM[F22];
 
 1084    if (s < low || s > high) 
return kTRUE;