00001 #include "Fireworks/Vertices/interface/TEveEllipsoidGL.h"
00002
00003 #define protected public
00004 #include "TEveProjections.h"
00005 #undef protected
00006
00007 #include "Fireworks/Vertices/interface/TEveEllipsoidGL.h"
00008 #include "Fireworks/Vertices/interface/TEveEllipsoid.h"
00009 #include "TEveProjectionManager.h"
00010
00011 #include "TMath.h"
00012
00013 #include "TGLRnrCtx.h"
00014
00015 #include "TMatrixDEigen.h"
00016 #include "TMatrixDSym.h"
00017
00018 #include "TDecompSVD.h"
00019 #include "TGLIncludes.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 TEveEllipsoidGL::TEveEllipsoidGL() :
00033 TGLObject(), fE(0)
00034 {
00035
00036
00037
00038 }
00039
00040
00041 Bool_t TEveEllipsoidGL::SetModel(TObject* obj, const Option_t* )
00042 {
00043
00044
00045 fE = SetModelDynCast<TEveEllipsoid>(obj);
00046 return kTRUE;
00047 }
00048
00049
00050 void TEveEllipsoidGL::SetBBox()
00051 {
00052
00053 ( (TEveEllipsoid*)fExternalObj)->ComputeBBox();
00054 SetAxisAlignedBBox(((TEveEllipsoid*)fExternalObj)->AssertBBox());
00055 }
00056
00057 namespace {
00058 GLUquadric* quad = 0;
00059 }
00060
00061
00062 void TEveEllipsoidGL::DirectDraw(TGLRnrCtx& ) const
00063 {
00064
00065
00066
00067
00068 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LIGHTING_BIT);
00069 glEnable(GL_NORMALIZE );
00070 if(!quad)
00071 quad = gluNewQuadric();
00072
00073 glPushMatrix();
00074
00075 TMatrixDSym xxx(3);
00076 for(int i=0;i<3;i++)
00077 for(int j=0;j<3;j++)
00078 {
00079 xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00080 }
00081 TMatrixDEigen eig(xxx);
00082
00083
00084
00085 TEveTrans x;
00086 for(int i=0;i<3;i++)
00087 for(int j=0;j<3;j++)
00088 {
00089 x(i+1, j+1) = eig.GetEigenVectors()(i,j);
00090 }
00091
00092 TVector3 a = x.GetBaseVec(1);
00093 TVector3 c = a.Cross(x.GetBaseVec(2));
00094 x.SetBaseVec(3, c);
00095
00096 glTranslatef(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
00097 glMultMatrixd(x.Array());
00098 glScalef(fE->RefExtent3D()[0] , fE->RefExtent3D()[1], fE->RefExtent3D()[2]);
00099 gluSphere(quad,1. , 30, 30);
00100
00101 glPopMatrix();
00102 glPopAttrib();
00103
00104
00105
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 TEveEllipsoidProjectedGL::TEveEllipsoidProjectedGL() :
00121 fM(0)
00122 {
00123
00124
00125
00126 fMultiColor = kTRUE;
00127 }
00128
00129
00130 Bool_t TEveEllipsoidProjectedGL::SetModel(TObject* obj, const Option_t* )
00131 {
00132
00133
00134 fM = SetModelDynCast<TEveEllipsoidProjected>(obj);
00135 fE = dynamic_cast<TEveEllipsoid*>(fM->GetProjectable());
00136 return fE != 0;
00137 }
00138
00139
00140 void TEveEllipsoidProjectedGL::SetBBox()
00141 {
00142
00143
00144 SetAxisAlignedBBox(((TEveEllipsoidProjected*)fExternalObj)->AssertBBox());
00145 }
00146
00147
00148 void TEveEllipsoidProjectedGL::DirectDraw(TGLRnrCtx& rnrCtx) const
00149 {
00150
00151
00152 TEveProjection *proj = fM->GetManager()->GetProjection();
00153
00154
00155 glPushAttrib(GL_ENABLE_BIT| GL_POLYGON_BIT | GL_LINE_BIT | GL_POINT_BIT);
00156 glDisable(GL_LIGHTING);
00157 glDisable(GL_CULL_FACE);
00158
00159 glPushMatrix();
00160 if ( proj->GetType() == TEveProjection::kPT_RPhi)
00161 DrawRhoPhi();
00162 else
00163 DrawRhoZ();
00164
00165 glPopMatrix();
00166 glPopAttrib();
00167 }
00168
00169
00170
00171 void TEveEllipsoidProjectedGL::drawArch(float phiStart, float phiEnd, float phiStep, TEveVector& v0, TEveVector& v1, TEveVector& v2) const
00172 {
00173 TEveProjection *proj = fM->GetManager()->GetProjection();
00174 float phi = phiStart;
00175 while (phi < phiEnd ) {
00176 TEveVector v = v0 + v1*((float)cos(phi)) + v2*((float)sin(phi));
00177 proj->ProjectVector(v, fM->fDepth);
00178 glVertex3fv(v.Arr());
00179
00180 phi += phiStep;
00181 }
00182 TEveVector v = v0 + v1*((float)cos(phiEnd)) + v2*((float)sin(phiEnd));
00183 proj->ProjectVector(v, fM->fDepth);
00184 glVertex3fv(v.Arr());
00185 }
00186
00187
00188 void TEveEllipsoidProjectedGL::DrawRhoPhi() const
00189 {
00190
00191
00192 TMatrixDSym xxx(3);
00193 for(int i=0;i<2;i++)
00194 for(int j=0;j<2;j++)
00195 {
00196 xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00197 }
00198
00199 TMatrixDEigen eig(xxx);
00200 TVectorD xxxEig ( eig.GetEigenValuesRe());
00201
00202
00203
00204 TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], 0);
00205 TEveVector v1(eig.GetEigenVectors()(0, 0) , eig.GetEigenVectors()(0, 1), 0 );
00206 v1 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[0]));
00207 TEveVector v2(eig.GetEigenVectors()(1, 0) , eig.GetEigenVectors()(1, 1), 0 );
00208 v2 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[1]));
00209
00210 TEveProjection *proj = fM->GetManager()->GetProjection();
00211
00212
00213 glBegin(GL_POLYGON);
00214 drawArch(0, TMath::TwoPi(), TMath::TwoPi()/20, v0, v1, v2);
00215 glEnd();
00216
00217
00218 TGLUtil::LineWidth(fE->fLineWidth);
00219 TGLUtil::Color(fE->fLineColor);
00220
00221 glBegin(GL_LINE_LOOP);
00222 drawArch(0, TMath::TwoPi(), TMath::TwoPi()/20, v0, v1, v2);
00223 glEnd();
00224
00225 glBegin(GL_LINES);
00226 {
00227
00228 TEveVector p1 = v0 - v1;
00229 TEveVector p2 = v0 + v1;
00230 proj->ProjectVector(p1, fM->fDepth);
00231 proj->ProjectVector(p2, fM->fDepth);
00232 glVertex3fv(p1.Arr());
00233 glVertex3fv(p2.Arr());
00234 }
00235 {
00236
00237 TEveVector p1 = v0 - v2;
00238 TEveVector p2 = v0 + v2;
00239 proj->ProjectVector(p1, fM->fDepth);
00240 proj->ProjectVector(p2, fM->fDepth);
00241 glVertex3fv(p1.Arr());
00242 glVertex3fv(p2.Arr());
00243 }
00244 glEnd();
00245
00246
00247
00248 }
00249
00250
00251 void TEveEllipsoidProjectedGL::DrawRhoZ() const
00252 {
00253
00254
00255 TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
00256
00257 TMatrixDSym xxx(3);
00258 xxx(0, 0) = 1;
00259 for(int i=1;i<3;i++)
00260 for(int j=1;j<3;j++)
00261 {
00262 xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00263 }
00264 TMatrixDEigen eig(xxx);
00265 TVectorD xxxEig ( eig.GetEigenValuesRe());
00266
00267
00268 TEveVector v1(0, eig.GetEigenVectors()(1, 2), eig.GetEigenVectors()(2, 2));
00269 v1 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[2]));
00270
00271 TEveVector v2(0, eig.GetEigenVectors()(1, 1), eig.GetEigenVectors()(2, 1));
00272 v2 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[1]));
00273 if (v1[1]*v2[2] > v1[2]*v2[1])
00274 v2 *= -1;
00275
00276
00277 TEveProjection *proj = fM->GetManager()->GetProjection();
00278
00279
00280 bool splitted = false;
00281 int N = 20;
00282 double phiStep = TMath::TwoPi()/N;
00283
00284
00285 float bs = 0;
00286 if (proj->GetDisplaceOrigin())
00287 bs = proj->fCenter[1];
00288
00289 float da = v2[1]*v2[1] + v1[1]*v1[1];
00290 float db = 2 * v1[1] * (v0[1]-bs);
00291 float dc = (v0[1]-bs)*(v0[1]-bs) - v2[1]*v2[1];
00292 float disc = (db*db -4*da*dc);
00293
00294 if ( disc > 0) {
00295 disc = sqrt(disc);
00296 float cosS1 = ( -db + disc)/(2 * da);
00297 float cosS2 = ( -db - disc)/(2 * da);
00298 if (TMath::Abs(cosS1) < 1) {
00299 splitted = true;
00300
00301
00302 double phi1 = acos(cosS1);
00303 double phi2 = acos(cosS2);
00304 TEveVector ps1 = v0 + v1*((float)cos(phi1)) + v2*((float)sin(phi1));
00305 TEveVector ps2 = v0 + v1*((float)cos(phi2)) + v2*((float)sin(phi2));
00306
00307
00308
00309
00310 if (TMath::Abs(ps1[1] - bs) > 1e-5)
00311 phi1 = TMath::TwoPi() -phi1;
00312
00313 if (TMath::Abs(ps2[1] - bs) > 1e-5)
00314 phi2 = TMath::TwoPi() -phi2;
00315
00316 int N = 20;
00317 double phiStep = TMath::TwoPi()/N;
00318 double phiOffset = phiStep*0.1;
00319 double phiMin = TMath::Min(phi1, phi2);
00320 double phiMax = TMath::Max(phi1, phi2);
00321
00322
00323
00324
00325 glBegin(GL_POLYGON);
00326 drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
00327 glEnd();
00328
00329 glBegin(GL_POLYGON);
00330 drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax -phiMin) - phiOffset, phiStep, v0, v1, v2);
00331 glEnd();
00332
00333
00334 TGLUtil::LineWidth(fE->fLineWidth);
00335 TGLUtil::Color(fE->fLineColor);
00336
00337 glBegin(GL_LINE_LOOP);
00338 drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
00339 glEnd();
00340
00341 glBegin(GL_LINE_LOOP);
00342 drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax -phiMin) - phiOffset, phiStep, v0, v1, v2);
00343 glEnd();
00344
00345 }
00346 }
00347
00348
00349 if (!splitted) {
00350 glBegin(GL_POLYGON);
00351 drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
00352 glEnd();
00353 TGLUtil::LineWidth(fE->fLineWidth);
00354 TGLUtil::Color(fE->fLineColor);
00355 glBegin(GL_LINE_LOOP);
00356 drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
00357 glEnd();
00358 }
00359
00360 drawRhoZAxis(v0, v2);
00361 drawRhoZAxis(v0, v1);
00362 }
00363
00364 void TEveEllipsoidProjectedGL::drawRhoZAxis(TEveVector& v0, TEveVector& v2) const
00365 {
00366 glBegin(GL_LINES);
00367 TEveProjection* proj = fM->GetManager()->GetProjection();
00368
00369 float bs = 0;
00370 if (proj->GetDisplaceOrigin())
00371 bs = proj->fCenter[1];
00372
00373 float off = (v2[1] > v0[1] ) ? 0.01 : -0.01;
00374 TEveVector alu = v0 + v2;
00375 proj->ProjectVector(alu, fM->fDepth);
00376 glVertex3fv(alu.Arr());
00377
00378 if (TMath::Abs(v0[1]/v2[1]) < 1 )
00379 {
00380 alu = v0 - ((float) ((1-off) *(v0[1]-bs)/v2[1])) * v2;
00381 proj->ProjectVector(alu, fM->fDepth);
00382 glVertex3fv(alu.Arr());
00383
00384
00385
00386 alu = v0 - ((float) ((1+off) * (v0[1]-bs)/v2[1])) * v2;
00387 proj->ProjectVector(alu, fM->fDepth);
00388 glVertex3fv(alu.Arr());
00389 }
00390
00391 alu = v0 - v2;
00392 proj->ProjectVector(alu, fM->fDepth);
00393 glVertex3fv(alu.Arr());
00394
00395 glEnd();
00396 }