// @(#)root/geom:$Name: $:$Id: TGeoMatrix.cxx,v 1.7 2003/05/07 14:21:56 brun Exp $
// Author: Andrei Gheata 25/10/01
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
// Author : Andrei Gheata - Wed 24 Oct 2001 09:46:13 AM CEST
////////////////////////////////////////////////////////////////////////////////
// Geometrical transformation package
//
//
//
//
//
/*
*/
//
#include "TObjArray.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
TGeoIdentity *gGeoIdentity = 0;
// statics and globals
ClassImp(TGeoMatrix)
ClassImp(TGeoTranslation)
ClassImp(TGeoRotation)
ClassImp(TGeoScale)
ClassImp(TGeoCombiTrans)
ClassImp(TGeoGenTrans)
ClassImp(TGeoIdentity)
//-----------------------------------------------------------------------------
TGeoMatrix::TGeoMatrix()
{
// dummy constructor
}
//-----------------------------------------------------------------------------
TGeoMatrix::TGeoMatrix(const char *name)
:TNamed(name, "")
{
// Constructor
if (!gGeoManager) gGeoManager = new TGeoManager("Geometry", "Default geometry");
}
//-----------------------------------------------------------------------------
Bool_t TGeoMatrix::IsRotAboutZ() const
{
// Returns true if no rotation or the rotation is about Z axis
if (IsIdentity()) return kTRUE;
const Double_t *rot = GetRotationMatrix();
if (TMath::Abs(rot[6])>1E-9) return kFALSE;
if (TMath::Abs(rot[7])>1E-9) return kFALSE;
if ((1.-TMath::Abs(rot[8]))>1E-9) return kFALSE;
return kTRUE;
}
//-----------------------------------------------------------------------------
Int_t TGeoMatrix::GetByteCount() const
{
// Get total size in bytes of this
Int_t count = 4+28+strlen(GetName())+strlen(GetTitle()); // fId + TNamed
if (IsTranslation()) count += 12;
if (IsScale()) count += 12;
if (IsCombi() || IsGeneral()) count += 4 + 36;
return count;
}
//-----------------------------------------------------------------------------
void TGeoMatrix::GetHomogenousMatrix(Double_t *hmat) const
{
// The homogenous matrix associated with the transformation is used for
// piling up's and visualization. A homogenous matrix is a 4*4 array
// containing the translation, the rotation and the scale components
//
// | R00*sx R01 R02 dx |
// | R10 R11*sy R12 dy |
// | R20 R21 R22*sz dz |
// | 0 0 0 1 |
//
// where Rij is the rotation matrix, (sx, sy, sz) is the scale
// transformation and (dx, dy, dz) is the translation.
Double_t *hmatrix = hmat;
const Double_t *mat = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
memcpy(hmatrix, mat, 3*sizeof(Double_t));
mat += 3;
hmatrix += 3;
*hmatrix = 0.0;
hmatrix++;
}
memcpy(hmatrix, GetTranslation(), 3*sizeof(Double_t));
hmatrix = hmat;
if (IsScale()) {
for (Int_t i=0; i<3; i++) {
*hmatrix *= GetScale()[i];
hmatrix += 5;
}
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
if (IsIdentity()) {
memcpy(master, local, 3*sizeof(Double_t));
return;
}
const Double_t *tr = GetTranslation();
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
master[i] = tr[i]
+ local[0]*rot[3*i]
+ local[1]*rot[3*i+1]
+ local[2]*rot[3*i+2];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master) const
{
// convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
if (IsIdentity()) {
memcpy(master, local, 3*sizeof(Double_t));
return;
}
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
master[i] = local[0]*rot[3*i]
+ local[1]*rot[3*i+1]
+ local[2]*rot[3*i+2];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::LocalToMasterBomb(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
if (IsIdentity()) {
memcpy(master, local, 3*sizeof(Double_t));
return;
}
const Double_t *tr = GetTranslation();
Double_t bombtr[3];
gGeoManager->BombTranslation(tr, &bombtr[0]);
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
master[i] = bombtr[i]
+ local[0]*rot[3*i]
+ local[1]*rot[3*i+1]
+ local[2]*rot[3*i+2];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
if (IsIdentity()) {
memcpy(local, master, 3*sizeof(Double_t));
return;
}
const Double_t *tr = GetTranslation();
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
local[i] = (master[0]-tr[0])*rot[i]
+ (master[1]-tr[1])*rot[i+3]
+ (master[2]-tr[2])*rot[i+6];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
if (IsIdentity()) {
memcpy(local, master, 3*sizeof(Double_t));
return;
}
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
local[i] = master[0]*rot[i]
+ master[1]*rot[i+3]
+ master[2]*rot[i+6];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::MasterToLocalBomb(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
if (IsIdentity()) {
memcpy(local, master, 3*sizeof(Double_t));
return;
}
const Double_t *tr = GetTranslation();
Double_t bombtr[3];
gGeoManager->UnbombTranslation(tr, &bombtr[0]);
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
local[i] = (master[0]-bombtr[0])*rot[i]
+ (master[1]-bombtr[1])*rot[i+3]
+ (master[2]-bombtr[2])*rot[i+6];
}
}
//-----------------------------------------------------------------------------
void TGeoMatrix::Print(Option_t *) const
{
// print the matrix in 4x4 format
const Double_t *rot = GetRotationMatrix();
const Double_t *tr = GetTranslation();
const Double_t *sc = GetScale();
printf("matrix %s - translation : %i rotation : %i scale : %in", GetName(),(Int_t)IsTranslation(),
(Int_t)IsRotation(), (Int_t)IsScale());
printf(" %g %g %g %gn", rot[0], rot[1], rot[2], (Double_t)0);
printf(" %g %g %g %gn", rot[3], rot[4], rot[5], (Double_t)0);
printf(" %g %g %g %gn", rot[6], rot[7], rot[8], (Double_t)0);
printf(" %g %g %g %gn", tr[0], tr[1], tr[2], (Double_t)1);
if (IsScale()) printf("Scale : %g %g %gn", sc[0], sc[1], sc[2]);
}
//-----------------------------------------------------------------------------
void TGeoMatrix::SetDefaultName()
{
// If no name was supplied in the ctor, the type of transformation is checked.
// A letter will be prepended to the name :
// t - translation
// r - rotation
// s - scale
// c - combi (translation + rotation)
// g - general (tr+rot+scale)
// The index of the transformation in gGeoManager list of transformations will
// be appended.
if (strlen(GetName())) return;
char type = 'n';
if (IsTranslation()) type = 't';
if (IsRotation()) type = 'r';
if (IsScale()) type = 's';
if (IsCombi()) type = 'c';
if (IsGeneral()) type = 'g';
TObjArray *matrices = gGeoManager->GetListOfMatrices();
Int_t index = 0;
if (matrices) index =matrices->GetEntriesFast() - 1;
Int_t digits = 1;
Int_t num = 10;
while ((Int_t)(index/num)) {
digits++;
num *= 10;
}
char *name = new char[digits+2];
sprintf(name, "%c%i", type, index);
SetName(name);
}
//-----------------------------------------------------------------------------
TGeoTranslation::TGeoTranslation()
{
// Default constructor
SetBit(kGeoTranslation);
for (Int_t i=0; i<3; i++) fTranslation[i] = 0;
}
//-----------------------------------------------------------------------------
TGeoTranslation::TGeoTranslation(Double_t dx, Double_t dy, Double_t dz)
:TGeoMatrix("")
{
// Default constructor defining the translation
SetBit(kGeoTranslation);
SetDefaultName();
SetTranslation(dx, dy, dz);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoTranslation::TGeoTranslation(const char *name, Double_t dx, Double_t dy, Double_t dz)
:TGeoMatrix(name)
{
// Default constructor defining the translation
SetBit(kGeoTranslation);
SetTranslation(dx, dy, dz);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
void TGeoTranslation::Add(TGeoTranslation *other)
{
// Adding a translation to this one
const Double_t *trans = other->GetTranslation();
for (Int_t i=0; i<3; i++)
fTranslation[i] += trans[i];
}
//-----------------------------------------------------------------------------
void TGeoTranslation::Subtract(TGeoTranslation *other)
{
// Subtracting a translation from this one
const Double_t *trans = other->GetTranslation();
for (Int_t i=0; i<3; i++)
fTranslation[i] -= trans[i];
}
//-----------------------------------------------------------------------------
void TGeoTranslation::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
{
// Set translation components
fTranslation[0] = dx;
fTranslation[1] = dy;
fTranslation[2] = dz;
}
//-----------------------------------------------------------------------------
void TGeoTranslation::LocalToMaster(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
const Double_t *tr = GetTranslation();
for (Int_t i=0; i<3; i++)
master[i] = tr[i] + local[i];
}
//-----------------------------------------------------------------------------
void TGeoTranslation::LocalToMasterVect(const Double_t *local, Double_t *master) const
{
// convert a vector to MARS
memcpy(master, local, 3*sizeof(Double_t));
}
//-----------------------------------------------------------------------------
void TGeoTranslation::LocalToMasterBomb(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
const Double_t *tr = GetTranslation();
Double_t bombtr[3];
gGeoManager->BombTranslation(tr, &bombtr[0]);
for (Int_t i=0; i<3; i++)
master[i] = bombtr[i] + local[i];
}
//-----------------------------------------------------------------------------
void TGeoTranslation::MasterToLocal(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
const Double_t *tr = GetTranslation();
for (Int_t i=0; i<3; i++)
local[i] = master[i]-tr[i];
}
//-----------------------------------------------------------------------------
void TGeoTranslation::MasterToLocalVect(const Double_t *master, Double_t *local) const
{
// convert a vector from MARS to local
memcpy(local, master, 3*sizeof(Double_t));
}
//-----------------------------------------------------------------------------
void TGeoTranslation::MasterToLocalBomb(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
const Double_t *tr = GetTranslation();
Double_t bombtr[3];
gGeoManager->UnbombTranslation(tr, &bombtr[0]);
for (Int_t i=0; i<3; i++)
local[i] = master[i]-bombtr[i];
}
//-----------------------------------------------------------------------------
TGeoRotation::TGeoRotation()
{
SetBit(kGeoRotation);
// dummy ctor
}
//-----------------------------------------------------------------------------
TGeoRotation::TGeoRotation(const char *name)
:TGeoMatrix(name)
{
// Default rotation constructor
for (Int_t i=0; i<9; i++) {
if (i%4) fRotationMatrix[i] = 0;
else fRotationMatrix[i] = 1.0;
}
SetBit(kGeoRotation);
SetDefaultName();
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoRotation::TGeoRotation(const char *name, Double_t phi, Double_t theta, Double_t psi)
:TGeoMatrix(name)
{
// Default rotation constructor with Euler angles. Phi is the rotation angle about
// Z axis and is done first, theta is the rotation about new Y and is done
// second, psi is the rotation angle about new Z and is done third. All angles are in
// degrees.
SetBit(kGeoRotation);
SetDefaultName();
SetAngles(phi, theta, psi);
CheckMatrix();
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoRotation::TGeoRotation(const char *name, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
Double_t theta3, Double_t phi3)
:TGeoMatrix(name)
{
// Rotation constructor a la GEANT3. Angles theta(i), phi(i) are the polar and azimuthal
// angles of the (i) axis of the rotated system with respect to the initial non-rotated
// system.
// Example : the identity matrix (no rotation) is composed by
// theta1=90, phi1=0, theta2=90, phi2=90, theta3=0, phi3=0
SetBit(kGeoRotation);
SetDefaultName();
SetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
CheckMatrix();
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
void TGeoRotation::Clear(Option_t *)
{
// reset data members to 0
memset(&fRotationMatrix[0], 0, 9*sizeof(Double_t));
}
//-----------------------------------------------------------------------------
void TGeoRotation::FastRotZ(Double_t *sincos)
{
fRotationMatrix[0] = sincos[1];
fRotationMatrix[1] = -sincos[0];
fRotationMatrix[3] = sincos[0];
fRotationMatrix[4] = sincos[1];
}
//-----------------------------------------------------------------------------
Double_t TGeoRotation::GetPhiRotation() const
{
//--- Returns rotation angle about Z axis in degrees.
Double_t phi = 180.*TMath::ATan2(fRotationMatrix[1], fRotationMatrix[0])/TMath::Pi();
return phi;
}
//-----------------------------------------------------------------------------
void TGeoRotation::LocalToMaster(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
master[i] = local[0]*rot[3*i]
+ local[1]*rot[3*i+1]
+ local[2]*rot[3*i+2];
}
}
//-----------------------------------------------------------------------------
void TGeoRotation::MasterToLocal(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
const Double_t *rot = GetRotationMatrix();
for (Int_t i=0; i<3; i++) {
local[i] = master[0]*rot[i]
+ master[1]*rot[i+3]
+ master[2]*rot[i+6];
}
}
//-----------------------------------------------------------------------------
void TGeoRotation::SetAngles(Double_t phi, Double_t theta, Double_t psi)
{
// Set matrix elements according to Euler angles
Double_t degrad = TMath::Pi()/180.;
Double_t sinphi = TMath::Sin(degrad*phi);
Double_t cosphi = TMath::Cos(degrad*phi);
Double_t sinthe = TMath::Sin(degrad*theta);
Double_t costhe = TMath::Cos(degrad*theta);
Double_t sinpsi = TMath::Sin(degrad*psi);
Double_t cospsi = TMath::Cos(degrad*psi);
fRotationMatrix[0] = cospsi*costhe*cosphi - sinpsi*sinphi;
fRotationMatrix[1] = -sinpsi*costhe*cosphi - cospsi*sinphi;
fRotationMatrix[2] = sinthe*cosphi;
fRotationMatrix[3] = cospsi*costhe*sinphi + sinpsi*cosphi;
fRotationMatrix[4] = -sinpsi*costhe*sinphi + cospsi*cosphi;
fRotationMatrix[5] = sinthe*sinphi;
fRotationMatrix[6] = -cospsi*sinthe;
fRotationMatrix[7] = sinpsi*sinthe;
fRotationMatrix[8] = costhe;
}
//-----------------------------------------------------------------------------
void TGeoRotation::SetAngles(Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
Double_t theta3, Double_t phi3)
{
// Set matrix elements in the GEANT3 way
Double_t degrad = TMath::Pi()/180.;
fRotationMatrix[0] = TMath::Cos(degrad*phi1)*TMath::Sin(degrad*theta1);
fRotationMatrix[3] = TMath::Sin(degrad*phi1)*TMath::Sin(degrad*theta1);
fRotationMatrix[6] = TMath::Cos(degrad*theta1);
fRotationMatrix[1] = TMath::Cos(degrad*phi2)*TMath::Sin(degrad*theta2);
fRotationMatrix[4] = TMath::Sin(degrad*phi2)*TMath::Sin(degrad*theta2);
fRotationMatrix[7] = TMath::Cos(degrad*theta2);
fRotationMatrix[2] = TMath::Cos(degrad*phi3)*TMath::Sin(degrad*theta3);
fRotationMatrix[5] = TMath::Sin(degrad*phi3)*TMath::Sin(degrad*theta3);
fRotationMatrix[8] = TMath::Cos(degrad*theta3);
// do the trick to eliminate most of the floating point errors
for (Int_t i=0; i<9; i++) {
if (TMath::Abs(fRotationMatrix[i])<1E-15) fRotationMatrix[i] = 0;
if (TMath::Abs(fRotationMatrix[i]-1)<1E-15) fRotationMatrix[i] = 1;
if (TMath::Abs(fRotationMatrix[i]+1)<1E-15) fRotationMatrix[i] = -1;
}
}
//-----------------------------------------------------------------------------
Double_t TGeoRotation::Determinant() const
{
// computes determinant of the rotation matrix
Double_t
det = fRotationMatrix[0]*fRotationMatrix[4]*fRotationMatrix[8] +
fRotationMatrix[3]*fRotationMatrix[7]*fRotationMatrix[1] +
fRotationMatrix[6]*fRotationMatrix[1]*fRotationMatrix[5] -
fRotationMatrix[2]*fRotationMatrix[4]*fRotationMatrix[6] -
fRotationMatrix[5]*fRotationMatrix[7]*fRotationMatrix[0] -
fRotationMatrix[7]*fRotationMatrix[1]*fRotationMatrix[3];
return det;
}
//-----------------------------------------------------------------------------
void TGeoRotation::CheckMatrix()
{
// performes an orthogonality check and finds if the matrix is a reflection
// Warning("CheckMatrix", "orthogonality check not performed yet");
if (Determinant() < 0) {
SetBit(kGeoReflection);
// printf("matrix %s is reflectionn", GetName());
}
}
//-----------------------------------------------------------------------------
void TGeoRotation::GetInverse(Double_t *invmat) const
{
// Get the inverse rotation matrix (which is simply the transpose)
if (!invmat) {
Error("GetInverse", "no place to store the inverse matrix");
}
for (Int_t i=0; i<3; i++) {
for (Int_t j=0; i<3; i++) {
invmat[3*i+j] = fRotationMatrix[3*j+i];
}
}
}
//-----------------------------------------------------------------------------
void TGeoRotation::MultiplyBy(TGeoRotation *rot, Bool_t after)
{
const Double_t *matleft, *matright;
Double_t newmat[9];
if (after) {
matleft = &fRotationMatrix[0];
matright = rot->GetRotationMatrix();
} else {
matleft = rot->GetRotationMatrix();
matright = &fRotationMatrix[0];
}
for (Int_t i=0; i<3; i++) {
for (Int_t j=0; j<3; j++) {
for (Int_t k=0; k<3; k++) {
newmat[3*i+j] = matleft[3*i+k] * matright[3*k+j];
}
}
}
memcpy(&fRotationMatrix[0], &newmat[0], 9*sizeof(Double_t));
}
//-----------------------------------------------------------------------------
TGeoScale::TGeoScale()
{
// default constructor
SetBit(kGeoScale);
for (Int_t i=0; i<3; i++) fScale[i] = 0;
}
//-----------------------------------------------------------------------------
TGeoScale::TGeoScale(Double_t sx, Double_t sy, Double_t sz)
:TGeoMatrix("")
{
// default constructor
SetBit(kGeoScale);
SetDefaultName();
SetScale(sx, sy, sz);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoScale::TGeoScale(const char *name, Double_t sx, Double_t sy, Double_t sz)
:TGeoMatrix(name)
{
// default constructor
SetBit(kGeoScale);
SetScale(sx, sy, sz);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoScale::~TGeoScale()
{
// destructor
}
//-----------------------------------------------------------------------------
void TGeoScale::SetScale(Double_t sx, Double_t sy, Double_t sz)
{
// scale setter
fScale[0] = sx;
fScale[1] = sy;
fScale[2] = sz;
if (!(Normalize())) {
Error("ctor", "Invalid scale");
return;
}
}
//-----------------------------------------------------------------------------
Bool_t TGeoScale::Normalize()
{
// A scale transformation should be normalized by sx*sy*sz factor
Double_t normfactor = fScale[0]*fScale[1]*fScale[2];
if (normfactor <= 1E-5) return kFALSE;
for (Int_t i=0; i<3; i++)
fScale[i] /= normfactor;
return kTRUE;
}
//-----------------------------------------------------------------------------
TGeoCombiTrans::TGeoCombiTrans()
{
// dummy ctor
SetBit(kGeoCombiTrans);
for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
fRotation = 0;
}
//-----------------------------------------------------------------------------
TGeoCombiTrans::TGeoCombiTrans(const char *name)
:TGeoMatrix(name)
{
// ctor
SetBit(kGeoCombiTrans);
SetDefaultName();
for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
fRotation = 0;
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoCombiTrans::TGeoCombiTrans(Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
:TGeoMatrix("")
{
// ctor
SetBit(kGeoCombiTrans);
SetDefaultName();
SetTranslation(dx, dy, dz);
SetRotation(rot);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoCombiTrans::TGeoCombiTrans(const char *name, Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
:TGeoMatrix(name)
{
// ctor
SetBit(kGeoCombiTrans);
SetTranslation(dx, dy, dz);
SetRotation(rot);
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
TGeoCombiTrans::~TGeoCombiTrans()
{
// destructor
}
//-----------------------------------------------------------------------------
void TGeoCombiTrans::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
{
// set the translation component
fTranslation[0] = dx;
fTranslation[1] = dy;
fTranslation[2] = dz;
}
//-----------------------------------------------------------------------------
void TGeoCombiTrans::SetTranslation(Double_t *vect)
{
// set the translation component
fTranslation[0] = vect[0];
fTranslation[1] = vect[1];
fTranslation[2] = vect[2];
}
//-----------------------------------------------------------------------------
const Double_t *TGeoCombiTrans::GetRotationMatrix() const
{
// get the rotation array
if (!fRotation) return 0;
return fRotation->GetRotationMatrix();
}
//-----------------------------------------------------------------------------
TGeoGenTrans::TGeoGenTrans()
{
// dummy ctor
SetBit(kGeoGenTrans);
for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
fRotation = 0;
}
//-----------------------------------------------------------------------------
TGeoGenTrans::TGeoGenTrans(const char *name)
:TGeoCombiTrans(name)
{
// ctor
SetBit(kGeoGenTrans);
for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
fRotation = 0;
}
//-----------------------------------------------------------------------------
TGeoGenTrans::TGeoGenTrans(Double_t dx, Double_t dy, Double_t dz,
Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
:TGeoCombiTrans("")
{
// ctor
SetBit(kGeoGenTrans);
SetDefaultName();
SetTranslation(dx, dy, dz);
SetScale(sx, sy, sz);
SetRotation(rot);
}
//-----------------------------------------------------------------------------
TGeoGenTrans::TGeoGenTrans(const char *name, Double_t dx, Double_t dy, Double_t dz,
Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
:TGeoCombiTrans(name)
{
// ctor
SetBit(kGeoGenTrans);
SetTranslation(dx, dy, dz);
SetScale(sx, sy, sz);
SetRotation(rot);
}
//-----------------------------------------------------------------------------
TGeoGenTrans::~TGeoGenTrans()
{
// destructor
}
//-----------------------------------------------------------------------------
void TGeoGenTrans::Clear(Option_t *)
{
// clear the fields of this transformation
memset(&fTranslation[0], 0, 3*sizeof(Double_t));
memset(&fScale[0], 0, 3*sizeof(Double_t));
fRotation->Clear();
}
//-----------------------------------------------------------------------------
void TGeoGenTrans::SetScale(Double_t sx, Double_t sy, Double_t sz)
{
// set the scale
fScale[0] = sx;
fScale[1] = sy;
fScale[2] = sz;
if (!(Normalize())) {
Error("ctor", "Invalid scale");
return;
}
}
//-----------------------------------------------------------------------------
Bool_t TGeoGenTrans::Normalize()
{
// A scale transformation should be normalized by sx*sy*sz factor
Double_t normfactor = fScale[0]*fScale[1]*fScale[2];
if (normfactor <= 1E-5) return kFALSE;
for (Int_t i=0; i<3; i++)
fScale[i] /= normfactor;
return kTRUE;
}
//-----------------------------------------------------------------------------
TGeoIdentity::TGeoIdentity()
{
// dummy ctor
}
//-----------------------------------------------------------------------------
TGeoIdentity::TGeoIdentity(const char *name)
:TGeoMatrix(name)
{
// ctor
if (!gGeoIdentity) gGeoIdentity = this;
gGeoManager->AddTransformation(this);
}
//-----------------------------------------------------------------------------
void TGeoIdentity::LocalToMaster(const Double_t *local, Double_t *master) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
memcpy(master, local, 3*sizeof(Double_t));
}
//-----------------------------------------------------------------------------
void TGeoIdentity::MasterToLocal(const Double_t *master, Double_t *local) const
{
// convert a point by multiplying its column vector (x, y, z, 1) to matrix
memcpy(local, master, 3*sizeof(Double_t));
}
/*************************************************************************
* TGeoHMatrix - Matrix class used for computing global transformations *
* Should NOT be used for node definition. An instance of this class *
* is generally used to pile-up local transformations starting from *
* the top level physical node, down to the current node. *
*************************************************************************/
ClassImp(TGeoHMatrix)
//-----------------------------------------------------------------------------
TGeoHMatrix::TGeoHMatrix()
{
// dummy ctor
memset(&fTranslation[0], 0, 3*sizeof(Double_t));
SetRotation(&kIdentityMatrix[0]);
SetScale(&kUnitScale[0]);
}
//-----------------------------------------------------------------------------
TGeoHMatrix::TGeoHMatrix(const char* name)
:TGeoMatrix(name)
{
// ctor
memset(&fTranslation[0], 0, 3*sizeof(Double_t));
SetRotation(&kIdentityMatrix[0]);
SetScale(&kUnitScale[0]);
}
//-----------------------------------------------------------------------------
TGeoHMatrix::~TGeoHMatrix()
{
// destructor
}
//-----------------------------------------------------------------------------
TGeoHMatrix &TGeoHMatrix::operator=(const TGeoMatrix *matrix)
{
// assignment
Clear();
if (matrix->IsIdentity()) return *this;
if (matrix->IsTranslation()) {
SetBit(kGeoTranslation);
SetTranslation(matrix->GetTranslation());
}
if (matrix->IsRotation()) {
SetBit(kGeoRotation);
SetRotation(matrix->GetRotationMatrix());
}
if (matrix->IsScale()) {
SetBit(kGeoScale);
SetScale(matrix->GetScale());
}
return *this;
}
//-----------------------------------------------------------------------------
void TGeoHMatrix::Clear(Option_t *)
{
// clear the data for this matrix
if (IsIdentity()) return;
if (IsTranslation()) {
ResetBit(kGeoTranslation);
SetTranslation(&kNullVector[0]);
}
if (IsRotation()) {
ResetBit(kGeoRotation);
SetRotation(&kIdentityMatrix[0]);
}
if (IsScale()) {
ResetBit(kGeoScale);
SetScale(&kUnitScale[0]);
}
}
//-----------------------------------------------------------------------------
void TGeoHMatrix::Multiply(TGeoMatrix *right)
{
// multiply to the right with an other transformation
// if right is identity matrix, just return
if (right == gGeoIdentity) return;
const Double_t *r_tra = right->GetTranslation();
const Double_t *r_rot = right->GetRotationMatrix();
const Double_t *r_scl = right->GetScale();
if (IsIdentity()) {
if (right->IsRotation()) {
SetBit(kGeoRotation);
SetRotation(r_rot);
}
if (right->IsScale()) {
SetBit(kGeoScale);
SetScale(r_scl);
}
if (right->IsTranslation()) {
SetBit(kGeoTranslation);
SetTranslation(r_tra);
}
return;
}
Int_t i, j;
Double_t new_tra[3];
Double_t new_rot[9];
Double_t new_scl[3];
if (right->IsRotation()) SetBit(kGeoRotation);
if (right->IsScale()) SetBit(kGeoScale);
if (right->IsTranslation()) SetBit(kGeoTranslation);
// new translation
if (IsTranslation()) {
for (i=0; i<3; i++) {
new_tra[i] = fTranslation[i]
+ fRotationMatrix[3*i]*r_tra[0]
+ fRotationMatrix[3*i+1]*r_tra[1]
+ fRotationMatrix[3*i+2]*r_tra[2];
}
SetTranslation(&new_tra[0]);
}
if (IsRotation()) {
// new rotation
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
new_rot[3*i+j] = fRotationMatrix[3*i]*r_rot[j] +
fRotationMatrix[3*i+1]*r_rot[3+j] +
fRotationMatrix[3*i+2]*r_rot[6+j];
}
}
SetRotation(&new_rot[0]);
}
// new scale
if (IsScale()) {
for (i=0; i<3; i++) new_scl[i] = fScale[i]*r_scl[i];
SetScale(&new_scl[0]);
}
}
//-----------------------------------------------------------------------------
void TGeoHMatrix::MultiplyLeft(TGeoMatrix *left)
{
// multiply to the right with an other transformation
// if right is identity matrix, just return
if (left == gGeoIdentity) return;
const Double_t *l_tra = left->GetTranslation();
const Double_t *l_rot = left->GetRotationMatrix();
const Double_t *l_scl = left->GetScale();
if (IsIdentity()) {
if (left->IsRotation()) {
SetBit(kGeoRotation);
SetRotation(l_rot);
}
if (left->IsScale()) {
SetBit(kGeoScale);
SetScale(l_scl);
}
if (left->IsTranslation()) {
SetBit(kGeoTranslation);
SetTranslation(l_tra);
}
return;
}
Int_t i, j;
Double_t new_tra[3];
Double_t new_rot[9];
Double_t new_scl[3];
if (left->IsRotation()) SetBit(kGeoRotation);
if (left->IsScale()) SetBit(kGeoScale);
if (left->IsTranslation()) SetBit(kGeoTranslation);
// new translation
if (IsTranslation()) {
for (i=0; i<3; i++) {
new_tra[i] = l_tra[i]
+ l_rot[3*i]* fTranslation[0]
+ l_rot[3*i+1]*fTranslation[1]
+ l_rot[3*i+2]*fTranslation[2];
}
SetTranslation(&new_tra[0]);
}
if (IsRotation()) {
// new rotation
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
new_rot[3*i+j] = l_rot[3*i]*fRotationMatrix[j] +
l_rot[3*i+1]*fRotationMatrix[3+j] +
l_rot[3*i+2]*fRotationMatrix[6+j];
}
}
SetRotation(&new_rot[0]);
}
// new scale
if (IsScale()) {
for (i=0; i<3; i++) new_scl[i] = fScale[i]*l_scl[i];
SetScale(&new_scl[0]);
}
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.