#include <algorithm>
#include "TError.h"
#include "TPoint.h"
#include "TStyle.h"
#include "TAxis.h"
#include "TMath.h"
#include "TH1.h"
#include "TGLPlotPainter.h"
#include "TGLIncludes.h"
#include "TGLQuadric.h"
#include "TGLUtil.h"
ClassImp(TGLPlotPainter)
ClassImp(TGLPlotFrame)
const Int_t TGLPlotFrame::fFramePlanes[][4] = {
{0, 4, 5, 1},
{1, 5, 6, 2},
{2, 6, 7, 3},
{0, 3, 7, 4},
{0, 1, 2, 3}
};
const Double_t TGLPlotFrame::fFrameNormals[][3] = {
{ 0., 1., 0.},
{-1., 0., 0.},
{ 0.,-1., 0.},
{ 1., 0., 0.},
{ 0., 0., 1.}
};
const Int_t TGLPlotFrame::fBackPairs[][2] = {
{2, 1},
{3, 2},
{0, 3},
{1, 0}
};
TGLPlotFrame::TGLPlotFrame(Bool_t logX, Bool_t logY, Bool_t logZ)
: fLogX(logX),
fLogY(logY),
fLogZ(logZ),
fScaleX(1.),
fScaleY(1.),
fScaleZ(1.),
fFrontPoint(0),
fViewport(),
fZoom(1.),
fFrustum(),
fShift(0.),
fCenter(),
fFactor(1.)
{
}
TGLPlotFrame::~TGLPlotFrame()
{
}
void TGLPlotFrame::AdjustShift(const TPoint &p1, const TPoint &p2, TGLVector3 &shiftVec,
const Int_t *viewport)
{
Double_t mv[16] = {0.};
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
Double_t pr[16] = {0.};
glGetDoublev(GL_PROJECTION_MATRIX, pr);
TGLVertex3 start, end;
gluUnProject(p1.fX, p1.fY, 1., mv, pr, viewport, &start.X(), &start.Y(), &start.Z());
gluUnProject(p2.fX, p2.fY, 1., mv, pr, viewport, &end.X(), &end.Y(), &end.Z());
shiftVec += (start - end) /= 2.;
}
void TGLPlotFrame::CalculateGLCameraParams(const Range_t &x, const Range_t &y, const Range_t &z)
{
const Double_t xRange = x.second - x.first;
const Double_t yRange = y.second - y.first;
const Double_t zRange = z.second - z.first;
const Double_t maxDim = TMath::Max(TMath::Max(xRange, yRange), zRange);
fScaleX = maxDim / xRange;
fScaleY = maxDim / yRange;
fScaleZ = maxDim / zRange;
const Double_t xMin = x.first * fScaleX, xMax = x.second * fScaleX;
const Double_t yMin = y.first * fScaleY, yMax = y.second * fScaleY;
const Double_t zMin = z.first * fScaleZ, zMax = z.second * fScaleZ;
fFrame[0].Set(xMin, yMin, zMin);
fFrame[1].Set(xMax, yMin, zMin);
fFrame[2].Set(xMax, yMax, zMin);
fFrame[3].Set(xMin, yMax, zMin);
fFrame[4].Set(xMin, yMin, zMax);
fFrame[5].Set(xMax, yMin, zMax);
fFrame[6].Set(xMax, yMax, zMax);
fFrame[7].Set(xMin, yMax, zMax);
fCenter[0] = x.first + xRange / 2;
fCenter[1] = y.first + yRange / 2;
fCenter[2] = z.first + zRange / 2;
fFrustum[0] = maxDim;
fFrustum[1] = maxDim;
fFrustum[2] = -100 * maxDim;
fFrustum[3] = 100 * maxDim;
fShift = maxDim * 1.5;
}
namespace {
bool Compare(const TGLVertex3 &v1, const TGLVertex3 &v2)
{
return v1.Z() < v2.Z();
}
}
void TGLPlotFrame::FindFrontPoint()
{
Double_t mvMatrix[16] = {0.};
glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
Double_t prMatrix[16] = {0.};
glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
const Double_t zMin = fFrame[0].Z();
const Double_t zMax = fFrame[4].Z();
for (Int_t i = 0; i < 4; ++i) {
gluProject(fFrame[i].X(), fFrame[i].Y(), zMin, mvMatrix, prMatrix, fViewport,
&f2DAxes[i].X(), &f2DAxes[i].Y(), &f2DAxes[i].Z());
gluProject(fFrame[i].X(), fFrame[i].Y(), zMax, mvMatrix, prMatrix, fViewport,
&f2DAxes[i + 4].X(), &f2DAxes[i + 4].Y(), &f2DAxes[i + 4].Z());
}
fFrontPoint = std::min_element(f2DAxes, f2DAxes + 4, ::Compare) - f2DAxes;
}
void TGLPlotFrame::SetTransformation()
{
glTranslated(0., 0., -fShift);
glMultMatrixd(fArcBall.GetRotMatrix());
glRotated(45., 1., 0., 0.);
glRotated(-45., 0., 1., 0.);
glRotated(-90., 0., 1., 0.);
glRotated(-90., 1., 0., 0.);
glTranslated(-fPan[0], -fPan[1], -fPan[2]);
glTranslated(-fCenter[0] * fScaleX, -fCenter[1] * fScaleY, -fCenter[2] * fScaleZ);
}
void TGLPlotFrame::SetCamera()
{
glViewport(fViewport[0], fViewport[1], fViewport[2], fViewport[3]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(
-fFrustum[0] * fZoom,
fFrustum[0] * fZoom,
-fFrustum[1] * fZoom,
fFrustum[1] * fZoom,
fFrustum[2],
fFrustum[3]
);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
namespace RootGL
{
namespace {
Double_t FindMinBinWidth(const TAxis *axis)
{
Int_t currBin = axis->GetFirst();
Double_t width = axis->GetBinWidth(currBin);
if (!axis->IsVariableBinSize())
return width;
++currBin;
for (const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
width = TMath::Min(width, axis->GetBinWidth(currBin));
return width;
}
}
Bool_t FindAxisRange(const TAxis *axis, Bool_t log, BinRange_t &bins, Range_t &range)
{
bins.first = axis->GetFirst(), bins.second = axis->GetLast();
range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
if (log) {
if (range.second <= 0.)
return kFALSE;
range.second = TMath::Log10(range.second);
if (range.first <= 0.) {
Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);
if (bin > bins.second)
return kFALSE;
if (axis->GetBinLowEdge(bin) <= 0.) {
++bin;
if (bin > bins.second)
return kFALSE;
}
bins.first = bin;
range.first = axis->GetBinLowEdge(bin);
}
range.first = TMath::Log10(range.first);
}
return kTRUE;
}
Bool_t FindAxisRange(TH1 *hist, Bool_t logZ, const BinRange_t &xBins, const BinRange_t &yBins,
Range_t &zRange, Double_t &factor, Bool_t errors)
{
const Bool_t minimum = hist->GetMinimumStored() != -1111;
const Bool_t maximum = hist->GetMaximumStored() != -1111;
const Double_t margin = gStyle->GetHistTopMargin();
zRange.second = hist->GetCellContent(xBins.first, yBins.first), zRange.first = zRange.second;
Double_t summ = 0.;
for (Int_t i = xBins.first; i <= xBins.second; ++i) {
for (Int_t j = yBins.first; j <= yBins.second; ++j) {
Double_t val = hist->GetCellContent(i, j);
if (val > 0. && errors)
val = TMath::Max(val, val + hist->GetCellError(i, j));
zRange.second = TMath::Max(val, zRange.second);
zRange.first = TMath::Min(val, zRange.first);
summ += val;
}
}
if (hist->GetMaximumStored() != -1111)
zRange.second = hist->GetMaximumStored();
if (hist->GetMinimumStored() != -1111)
zRange.first = hist->GetMinimumStored();
if (logZ && zRange.second <= 0.)
return kFALSE;
if (zRange.first >= zRange.second)
zRange.first = 0.001 * zRange.second;
factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
if (summ) factor /= summ;
if (!factor) factor = 1.;
if (factor < 0.)
Warning("TGLPlotPainter::ExtractAxisZInfo",
"Negative factor, negative ranges - possible incorrect behavior");
zRange.second *= factor;
zRange.first *= factor;
if (logZ) {
if (zRange.first <= 0.)
zRange.first = TMath::Min(1., 0.001 * zRange.second);
zRange.first = TMath::Log10(zRange.first);
if (!minimum)
zRange.first += TMath::Log10(0.5);
zRange.second = TMath::Log10(zRange.second);
if (!maximum)
zRange.second += TMath::Log10(2*(0.9/0.95));
return kTRUE;
}
if (!maximum)
zRange.second += margin * (zRange.second - zRange.first);
if (!minimum) {
if (gStyle->GetHistMinimumZero())
zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
else
zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
}
return kTRUE;
}
void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin,
Double_t yMax, Double_t zMin, Double_t zMax)
{
GLUquadric *quad = quadric->Get();
if (quad) {
if (zMin > zMax)
std::swap(zMin, zMax);
const Double_t xCenter = xMin + (xMax - xMin) / 2;
const Double_t yCenter = yMin + (yMax - yMin) / 2;
const Double_t radius = TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2);
glPushMatrix();
glTranslated(xCenter, yCenter, zMin);
gluCylinder(quad, radius, radius, zMax - zMin, 40, 1);
glPopMatrix();
glPushMatrix();
glTranslated(xCenter, yCenter, zMax);
gluDisk(quad, 0., radius, 40, 1);
glPopMatrix();
glPushMatrix();
glTranslated(xCenter, yCenter, zMin);
glRotated(180., 0., 1., 0.);
gluDisk(quad, 0., radius, 40, 1);
glPopMatrix();
}
}
void DrawQuadOutline(const TGLVertex3 &v1, const TGLVertex3 &v2,
const TGLVertex3 &v3, const TGLVertex3 &v4)
{
glBegin(GL_LINE_LOOP);
glVertex3dv(v1.CArr());
glVertex3dv(v2.CArr());
glVertex3dv(v3.CArr());
glVertex3dv(v4.CArr());
glEnd();
}
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2,
const TGLVertex3 &v3, const TGLVertex3 &normal)
{
glBegin(GL_POLYGON);
glNormal3dv(normal.CArr());
glVertex3dv(v0.CArr());
glVertex3dv(v1.CArr());
glVertex3dv(v2.CArr());
glVertex3dv(v3.CArr());
glEnd();
}
const Int_t gBoxFrontQuads[][4] = {{0, 1, 2, 3}, {4, 0, 3, 5}, {4, 5, 6, 7}, {7, 6, 2, 1}};
const Double_t gBoxFrontNormals[][3] = {{-1., 0., 0.}, {0., -1., 0.}, {1., 0., 0.}, {0., 1., 0.}};
const Int_t gBoxFrontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
Double_t zMin, Double_t zMax, Int_t fp)
{
if (zMax < zMin)
std::swap(zMax, zMin);
glBegin(GL_POLYGON);
glNormal3d(0., 0., 1.);
glVertex3d(xMax, yMin, zMax);
glVertex3d(xMax, yMax, zMax);
glVertex3d(xMin, yMax, zMax);
glVertex3d(xMin, yMin, zMax);
glEnd();
glBegin(GL_POLYGON);
glNormal3d(0., 0., -1.);
glVertex3d(xMax, yMin, zMin);
glVertex3d(xMin, yMin, zMin);
glVertex3d(xMin, yMax, zMin);
glVertex3d(xMax, yMax, zMin);
glEnd();
const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
{xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
glBegin(GL_POLYGON);
glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][0]]);
glVertex3dv(box[verts[0]]);
glVertex3dv(box[verts[1]]);
glVertex3dv(box[verts[2]]);
glVertex3dv(box[verts[3]]);
glEnd();
verts = gBoxFrontQuads[gBoxFrontPlanes[fp][1]];
glBegin(GL_POLYGON);
glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[fp][1]]);
glVertex3dv(box[verts[0]]);
glVertex3dv(box[verts[1]]);
glVertex3dv(box[verts[2]]);
glVertex3dv(box[verts[3]]);
glEnd();
}
void DrawBoxFrontTextured(Double_t x1, Double_t x2, Double_t y1, Double_t y2, Double_t z1,
Double_t z2, Double_t texMin, Double_t texMax, Int_t frontPoint)
{
if (z2 < z1) {
std::swap(z2, z1);
std::swap(texMin, texMax);
}
glBegin(GL_POLYGON);
glNormal3d(0., 0., 1.);
glTexCoord1d(texMax); glVertex3d(x2, y1, z2);
glTexCoord1d(texMax); glVertex3d(x2, y2, z2);
glTexCoord1d(texMax); glVertex3d(x1, y2, z2);
glTexCoord1d(texMax); glVertex3d(x1, y1, z2);
glEnd();
glBegin(GL_POLYGON);
glNormal3d(0., 0., -1.);
glTexCoord1d(texMin); glVertex3d(x2, y1, z1);
glTexCoord1d(texMin); glVertex3d(x1, y1, z1);
glTexCoord1d(texMin); glVertex3d(x1, y2, z1);
glTexCoord1d(texMin); glVertex3d(x2, y2, z1);
glEnd();
const Double_t box[][3] = {{x1, y1, z2}, {x1, y2, z2}, {x1, y2, z1}, {x1, y1, z1},
{x2, y1, z2}, {x2, y1, z1}, {x2, y2, z1}, {x2, y2, z2}};
const Double_t z[] = {texMax, texMax, texMin, texMin, texMax, texMin, texMin, texMax};
const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[frontPoint][0]];
glBegin(GL_POLYGON);
glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[frontPoint][0]]);
glTexCoord1d(z[verts[0]]), glVertex3dv(box[verts[0]]);
glTexCoord1d(z[verts[1]]), glVertex3dv(box[verts[1]]);
glTexCoord1d(z[verts[2]]), glVertex3dv(box[verts[2]]);
glTexCoord1d(z[verts[3]]), glVertex3dv(box[verts[3]]);
glEnd();
verts = gBoxFrontQuads[gBoxFrontPlanes[frontPoint][1]];
glBegin(GL_POLYGON);
glNormal3dv(gBoxFrontNormals[gBoxFrontPlanes[frontPoint][1]]);
glTexCoord1d(z[verts[0]]), glVertex3dv(box[verts[0]]);
glTexCoord1d(z[verts[1]]), glVertex3dv(box[verts[1]]);
glTexCoord1d(z[verts[2]]), glVertex3dv(box[verts[2]]);
glTexCoord1d(z[verts[3]]), glVertex3dv(box[verts[3]]);
glEnd();
}
namespace {
void CylindricalNormal(const Double_t *v, Double_t *normal)
{
const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
if (n > 0.) {
normal[0] = v[0] / n;
normal[1] = v[1] / n;
normal[2] = 0.;
} else {
normal[0] = v[0];
normal[1] = v[1];
normal[2] = 0.;
}
}
void CylindricalNormalInv(const Double_t *v, Double_t *normal)
{
const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
if (n > 0.) {
normal[0] = -v[0] / n;
normal[1] = -v[1] / n;
normal[2] = 0.;
} else {
normal[0] = -v[0];
normal[1] = -v[1];
normal[2] = 0.;
}
}
}
void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color)
{
if (zMin > zMax)
std::swap(zMin, zMax);
glBegin(GL_POLYGON);
glNormal3d(0., 0., 1.);
glVertex3d(ver[0][0], ver[0][1], zMax);
glVertex3d(ver[1][0], ver[1][1], zMax);
glVertex3d(ver[2][0], ver[2][1], zMax);
glVertex3d(ver[3][0], ver[3][1], zMax);
glEnd();
glBegin(GL_POLYGON);
glNormal3d(0., 0., -1.);
glVertex3d(ver[0][0], ver[0][1], zMin);
glVertex3d(ver[3][0], ver[3][1], zMin);
glVertex3d(ver[2][0], ver[2][1], zMin);
glVertex3d(ver[1][0], ver[1][1], zMin);
glEnd();
Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
{ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
{ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
{ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
Double_t normal[3] = {0.};
glBegin(GL_POLYGON);
CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glVertex3dv(trapezoid[1]);
CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glVertex3dv(trapezoid[2]);
CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glVertex3dv(trapezoid[6]);
CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glVertex3dv(trapezoid[5]);
glEnd();
glBegin(GL_POLYGON);
CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glVertex3dv(trapezoid[0]);
CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glVertex3dv(trapezoid[4]);
CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glVertex3dv(trapezoid[7]);
CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glVertex3dv(trapezoid[3]);
glEnd();
glBegin(GL_POLYGON);
if (color) {
TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
glNormal3dv(normal);
}
glVertex3dv(trapezoid[0]);
glVertex3dv(trapezoid[1]);
glVertex3dv(trapezoid[5]);
glVertex3dv(trapezoid[4]);
glEnd();
glBegin(GL_POLYGON);
if (color) {
TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
glNormal3dv(normal);
}
glVertex3dv(trapezoid[3]);
glVertex3dv(trapezoid[7]);
glVertex3dv(trapezoid[6]);
glVertex3dv(trapezoid[2]);
glEnd();
}
namespace {
void SphericalNormal(const Double_t *v, Double_t *normal)
{
const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (n > 0.) {
normal[0] = v[0] / n;
normal[1] = v[1] / n;
normal[2] = v[2] / n;
} else {
normal[0] = v[0];
normal[1] = v[1];
normal[2] = v[2];
}
}
void SphericalNormalInv(const Double_t *v, Double_t *normal)
{
const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (n > 0.) {
normal[0] = -v[0] / n;
normal[1] = -v[1] / n;
normal[2] = -v[2] / n;
} else {
normal[0] = -v[0];
normal[1] = -v[1];
normal[2] = -v[2];
}
}
}
void DrawTrapezoid(const Double_t ver[][3])
{
Double_t normal[3] = {0.};
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
glNormal3dv(normal);
glVertex3dv(ver[0]);
glVertex3dv(ver[1]);
glVertex3dv(ver[2]);
glVertex3dv(ver[3]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
glNormal3dv(normal);
glVertex3dv(ver[4]);
glVertex3dv(ver[7]);
glVertex3dv(ver[6]);
glVertex3dv(ver[5]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
glNormal3dv(normal);
glVertex3dv(ver[0]);
glVertex3dv(ver[3]);
glVertex3dv(ver[7]);
glVertex3dv(ver[4]);
glEnd();
glBegin(GL_POLYGON);
SphericalNormal(ver[3], normal), glNormal3dv(normal), glVertex3dv(ver[3]);
SphericalNormal(ver[2], normal), glNormal3dv(normal), glVertex3dv(ver[2]);
SphericalNormal(ver[6], normal), glNormal3dv(normal), glVertex3dv(ver[6]);
SphericalNormal(ver[7], normal), glNormal3dv(normal), glVertex3dv(ver[7]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
glNormal3dv(normal);
glVertex3dv(ver[5]);
glVertex3dv(ver[6]);
glVertex3dv(ver[2]);
glVertex3dv(ver[1]);
glEnd();
glBegin(GL_POLYGON);
SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glVertex3dv(ver[0]);
SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glVertex3dv(ver[4]);
SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glVertex3dv(ver[5]);
SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glVertex3dv(ver[1]);
glEnd();
}
void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax,
Double_t texMin, Double_t texMax)
{
if (zMin > zMax) {
std::swap(zMin, zMax);
std::swap(texMin, texMax);
}
const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
{ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
{ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
{ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
glBegin(GL_POLYGON);
glNormal3d(0., 0., 1.);
glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
glEnd();
glBegin(GL_POLYGON);
glNormal3d(0., 0., -1.);
glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
glEnd();
glBegin(GL_POLYGON);
Double_t normal[3] = {};
CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
glEnd();
glBegin(GL_POLYGON);
CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
glNormal3dv(normal);
glTexCoord1d(texMin), glVertex3dv(trapezoid[0]);
glTexCoord1d(texMin), glVertex3dv(trapezoid[1]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[5]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[4]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
glNormal3dv(normal);
glTexCoord1d(texMin), glVertex3dv(trapezoid[3]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[7]);
glTexCoord1d(texMax), glVertex3dv(trapezoid[6]);
glTexCoord1d(texMin), glVertex3dv(trapezoid[2]);
glEnd();
}
void DrawTrapezoidTextured(const Double_t ver[][3], Double_t texMin, Double_t texMax)
{
Double_t normal[3] = {};
if (texMin > texMax)
std::swap(texMin, texMax);
const Double_t tex[] = {texMin, texMin, texMax, texMax, texMin, texMin, texMax, texMax};
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
glNormal3dv(normal);
glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
glNormal3dv(normal);
glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
glNormal3dv(normal);
glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
glEnd();
glBegin(GL_POLYGON);
SphericalNormal(ver[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(ver[3]);
SphericalNormal(ver[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
SphericalNormal(ver[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
SphericalNormal(ver[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(ver[7]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
glNormal3dv(normal);
glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
glTexCoord1d(tex[6]), glVertex3dv(ver[6]);
glTexCoord1d(tex[2]), glVertex3dv(ver[2]);
glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
glEnd();
glBegin(GL_POLYGON);
SphericalNormalInv(ver[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(ver[0]);
SphericalNormalInv(ver[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(ver[4]);
SphericalNormalInv(ver[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(ver[5]);
SphericalNormalInv(ver[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(ver[1]);
glEnd();
}
void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax,
Double_t texMin, Double_t texMax)
{
if (zMin > zMax) {
std::swap(zMin, zMax);
std::swap(texMin, texMax);
}
const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
{ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
{ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
{ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
const Double_t tex[] = {texMin, texMax, texMax, texMin, texMin, texMax, texMax, texMin};
glBegin(GL_POLYGON);
glNormal3d(0., 0., 1.);
glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
glEnd();
glBegin(GL_POLYGON);
glNormal3d(0., 0., -1.);
glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
glEnd();
glBegin(GL_POLYGON);
Double_t normal[3] = {};
CylindricalNormal(trapezoid[1], normal), glNormal3dv(normal), glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
CylindricalNormal(trapezoid[2], normal), glNormal3dv(normal), glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
CylindricalNormal(trapezoid[6], normal), glNormal3dv(normal), glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
CylindricalNormal(trapezoid[5], normal), glNormal3dv(normal), glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
glEnd();
glBegin(GL_POLYGON);
CylindricalNormalInv(trapezoid[0], normal), glNormal3dv(normal), glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
CylindricalNormalInv(trapezoid[4], normal), glNormal3dv(normal), glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
CylindricalNormalInv(trapezoid[7], normal), glNormal3dv(normal), glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
CylindricalNormalInv(trapezoid[3], normal), glNormal3dv(normal), glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(trapezoid[0], trapezoid[1], trapezoid[5], normal);
glNormal3dv(normal);
glTexCoord1d(tex[0]), glVertex3dv(trapezoid[0]);
glTexCoord1d(tex[1]), glVertex3dv(trapezoid[1]);
glTexCoord1d(tex[5]), glVertex3dv(trapezoid[5]);
glTexCoord1d(tex[4]), glVertex3dv(trapezoid[4]);
glEnd();
glBegin(GL_POLYGON);
TMath::Normal2Plane(trapezoid[3], trapezoid[7], trapezoid[6], normal);
glNormal3dv(normal);
glTexCoord1d(tex[3]), glVertex3dv(trapezoid[3]);
glTexCoord1d(tex[7]), glVertex3dv(trapezoid[7]);
glTexCoord1d(tex[6]), glVertex3dv(trapezoid[6]);
glTexCoord1d(tex[2]), glVertex3dv(trapezoid[2]);
glEnd();
}
void DrawError(Double_t xMin, Double_t xMax, Double_t yMin,
Double_t yMax, Double_t zMin, Double_t zMax)
{
const Double_t xWid = xMax - xMin;
const Double_t yWid = yMax - yMin;
glBegin(GL_LINES);
glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMin);
glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMax);
glEnd();
glBegin(GL_LINES);
glVertex3d(xMin + xWid / 2, yMin, zMin);
glVertex3d(xMin + xWid / 2, yMax, zMin);
glEnd();
glBegin(GL_LINES);
glVertex3d(xMin, yMin + yWid / 2, zMin);
glVertex3d(xMax, yMin + yWid / 2, zMin);
glEnd();
}
}
ROOT page - Class index - Class Hierarchy - 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.