using namespace std;
#include "hmdcgeomobj.h"
ClassImp(HMdcPointPlane)
ClassImp(HMdcTrap)
ClassImp(HMdcTrapPlane)
ClassImp(HMdcPlane)
ClassImp(HMdcPointOnPlane)
ClassImp(HMdcLineParam)
void HMdcPointPlane::print() const {
printf("x=%7f y=%7f\n",x,y);
}
HMdcTrap::HMdcTrap(const HMdcTrap& otrap) {
for(Int_t i=0; i<8; i++) points[i] = otrap.points[i];
dbPoint = otrap.dbPoint;
}
HGeomVector& HMdcTrap::operator[](Int_t i) {
if(i<0 || i>7) {
Error("operator[]","index=%i out of bounds! Set index=0", i);
return points[0];
}
return points[i];
}
void HMdcTrap::copy(HMdcTrap& otrap) const {
for(Int_t i=0; i<8; i++) otrap.points[i]=points[i];
otrap.dbPoint = dbPoint;
}
void HMdcTrap::set(const HMdcTrap& otrap) {
for(Int_t i=0; i<8; i++) points[i]=otrap.points[i];
dbPoint = otrap.dbPoint;
}
void HMdcTrap::clear() {
for(Int_t i=0; i<8; i++) points[i].clear();
dbPoint = -1;
}
void HMdcTrap::transFrom(const HGeomTransform &s) {
for(Int_t i=0; i<8; i++) points[i]=s.transFrom(points[i]);
}
void HMdcTrap::transTo(const HGeomTransform &s) {
for(Int_t i=0; i<8; i++) points[i]=s.transTo(points[i]);
}
Bool_t HMdcTrap::getRibInd(Int_t rib,Int_t& ind1,Int_t& ind2) {
if(rib<0 || rib>11) return kFALSE;
if(rib < 4) {
if(dbPoint>=0 && rib==dbPoint) return kFALSE;
ind1 = rib;
ind2 = nextPoint(ind1);
if(ind2 == dbPoint) ind2 = nextPoint(ind2);
} else if(rib < 8) {
if(dbPoint>=0 && rib==dbPoint+4) return kFALSE;
ind1 = rib;
ind2 = nextPoint(ind1);
if(ind2 == dbPoint+4) ind2 = nextPoint(ind2);
} else {
if(dbPoint>=0 && rib==dbPoint+8) return kFALSE;
ind1 = rib-8;
ind2 = ind1+4;
}
return kTRUE;
}
Bool_t HMdcTrap::getRibInXYContour(Int_t rib,Int_t& i,Int_t& j) {
if(!getRibInd(rib,i,j)) return kFALSE;
Double_t x2 = points[j](0);
Double_t y2 = points[j](1);
Double_t dX = points[i](0)-x2;
Double_t dY = points[i](1)-y2;
if(fabs(dX) > fabs(dY)) {
if(dX == 0.) return kFALSE;
Double_t coeff = dY/dX;
Short_t fl = 0;
for(Int_t k=0;k<8;k++) if(k!=i && k!=j) {
Double_t yt = (points[k](0)-x2)*coeff + y2 - points[k](1);
if(yt > 0.0) fl |= 1;
else if(yt < 0.0) fl |= 2;
if(fl==3) return kFALSE;
}
} else {
if(dY == 0.) return kFALSE;
Double_t coeff = dX/dY;
Short_t fl = 0;
for(Int_t k=0;k<8;k++) if(k!=i && k!=j) {
Double_t xt = (points[k](1)-y2)*coeff + x2 - points[k](0);
if(xt > 0.0) fl |= 1;
else if(xt < 0.0) fl |= 2;
if(fl==3) return kFALSE;
}
}
return kTRUE;
}
Int_t HMdcTrap::getXYContour(HMdcTrapPlane& tr) {
Int_t p1[12],p2[12];
Int_t nRibs = 0;
Int_t i,j;
for(Int_t rib=0;rib<12;rib++) if(getRibInXYContour(rib,i,j)) {
p1[nRibs] = i;
p2[nRibs] = j;
nRibs++;
}
tr.clearNPoints();
Int_t pnt0 = p1[0];
Int_t pnt = p2[0];
tr.addPoint(points[pnt0]);
tr.addPoint(points[pnt]);
Int_t nPOut = 2;
for(Int_t nr=1;nr<nRibs;nr++) if(p1[nr]>=0) {
if (p1[nr] == pnt) pnt = p2[nr];
else if(p2[nr] == pnt) pnt = p1[nr];
else continue;
if(pnt == pnt0) break;
tr.addPoint(points[pnt]);
nPOut++;
p1[nr] = -1;
nr = 0;
}
tr.calcDir();
return nPOut;
}
void HMdcTrap::print() {
printf("\nTrap. from 8 points:\n");
for(Int_t i=0; i<8; i++) {
printf("%2i) ",i);
points[i].print();
}
}
HMdcTrapPlane::HMdcTrapPlane(const HMdcTrapPlane& otrap) {
nPoints = otrap.nPoints;
xMinPoint = otrap.xMinPoint;
xMaxPoint = otrap.xMaxPoint;
yMinPoint = otrap.yMinPoint;
yMaxPoint = otrap.yMaxPoint;
dir = otrap.dir;
for(Int_t i=0; i<nPoints; i++) points[i].set(otrap.points[i]);
}
HMdcPointPlane& HMdcTrapPlane:: operator[](Int_t i) {
if(i<0 || i>=nPoints) {
Error("operator[]","index=%i out of bounds! Set index=0", i);
return points[0];
}
return points[i];
}
void HMdcTrapPlane::copy(HMdcTrapPlane& otrap) {
otrap.nPoints = nPoints;
otrap.xMinPoint = xMinPoint;
otrap.xMaxPoint = xMaxPoint;
otrap.yMinPoint = yMinPoint;
otrap.yMaxPoint = yMaxPoint;
otrap.dir = dir;
for(Int_t i=0; i<nPoints; i++) points[i].copy(otrap.points[i]);
}
void HMdcTrapPlane::set(const HMdcTrapPlane& otrap) {
nPoints = otrap.nPoints;
xMinPoint = otrap.xMinPoint;
xMaxPoint = otrap.xMaxPoint;
yMinPoint = otrap.yMinPoint;
yMaxPoint = otrap.yMaxPoint;
dir = otrap.dir;
for(Int_t i=0; i<nPoints; i++) points[i].set(otrap.points[i]);
}
void HMdcTrapPlane::clear() {
xMinPoint = 0;
xMaxPoint = 0;
yMinPoint = 0;
yMaxPoint = 0;
dir = 0;
for(Int_t i=0; i<nPoints; i++) points[i].clear();
}
void HMdcTrapPlane::clearNPoints(void) {
nPoints = 0;
xMinPoint = 0;
xMaxPoint = 0;
yMinPoint = 0;
yMaxPoint = 0;
dir = 0;
}
void HMdcTrapPlane::print() const {
printf("\nPolygon on the plane from %i points:\n",nPoints);
for(Int_t i=0; i<nPoints; i++) {
printf("%2i) ",i);
points[i].print();
}
}
void HMdcTrapPlane::addPoint(const HGeomVector& v) {
if(nPoints<16) {
points[nPoints].set(v.getX(),v.getY());
if(nPoints>0) {
if(points[yMinPoint].getY() > v.getY()) yMinPoint = nPoints;
if(points[yMaxPoint].getY() < v.getY()) yMaxPoint = nPoints;
if(points[xMinPoint].getX() > v.getX()) xMinPoint = nPoints;
if(points[xMaxPoint].getX() < v.getX()) xMaxPoint = nPoints;
}
nPoints++;
} else Error("addPoint","Too many points (>16).");
}
void HMdcTrapPlane::addPoint(const HMdcPointPlane& p) {
if(nPoints<16) {
points[nPoints].set(p);
if(nPoints>0) {
if(points[yMinPoint].getY() > p.getY()) yMinPoint = nPoints;
if(points[yMaxPoint].getY() < p.getY()) yMaxPoint = nPoints;
if(points[xMinPoint].getX() > p.getX()) xMinPoint = nPoints;
if(points[xMaxPoint].getX() < p.getX()) xMaxPoint = nPoints;
}
nPoints++;
} else Error("addPoint","Too many points (>16).");
}
void HMdcTrapPlane::calcDir(void) {
if(nPoints<3) dir = 0;
else {
Int_t p1 = prevP(yMinPoint);
Int_t p2 = nextP(yMinPoint);
Double_t y1 = points[p1].getY();
Double_t y2 = points[p2].getY();
Double_t x1 = points[p1].getX();
Double_t x2 = points[p2].getX();
if(y1<y2) x2 = calcX(yMinPoint,p2,y1);
else if(y1>y2) x1 = calcX(yMinPoint,p1,y2);
dir = x1 < x2 ? 1 : -1;
}
}
void HMdcTrapPlane::getXYMinMax(Int_t& xMin,Int_t& xMax,
Int_t& yMin,Int_t& yMax) const {
xMin = yMin = 0;
xMax = yMax = 0;
for(Int_t p=1;p<nPoints;p++) {
if(points[yMin].getY() > points[p].getY()) yMin = p;
if(points[yMax].getY() < points[p].getY()) yMax = p;
if(points[xMin].getX() > points[p].getX()) xMin = p;
if(points[xMax].getX() < points[p].getX()) xMax = p;
}
}
Int_t HMdcTrapPlane::twoContoursSum(const HMdcTrapPlane& c1i,
const HMdcTrapPlane& c2i) {
clearNPoints();
Bool_t c1imin = c1i.getYMin() < c2i.getYMin();
const HMdcTrapPlane& c1 = c1imin ? c1i : c2i;
const HMdcTrapPlane& c2 = c1imin ? c2i : c1i;
for(Int_t p=c1.yMinPoint;p!=c1.xMaxPoint;p=c1.nextXMaxP(p)) addPoint(c1.points[p]);
addPoint(c1.points[c1.xMaxPoint]);
for(Int_t p=c2.xMaxPoint;p!=c2.xMinPoint;p=c2.nextXMaxP(p)) addPoint(c2.points[p]);
addPoint(c2.points[c2.xMinPoint]);
for(Int_t p=c1.xMinPoint;p!=c1.yMinPoint;p=c1.prevXMinP(p)) addPoint(c1.points[p]);
calcDir();
return nPoints;
}
Bool_t HMdcTrapPlane::getLineInd(Int_t line, Int_t& p1,Int_t& p2) const {
if(line>=nPoints) return kFALSE;
p1 = line;
p2 = p1+1;
if(p2 == nPoints) p2 = 0;
return kTRUE;
}
Bool_t HMdcTrapPlane::getXCross(Int_t line,Double_t y, Double_t& x) const {
Int_t ip1,ip2;
if( !getLineInd(line,ip1,ip2) ) return kFALSE;
const HMdcPointPlane& p1 = points[ip1];
const HMdcPointPlane& p2 = points[ip2];
Double_t y1 = p1.getY();
Double_t y2 = p2.getY();
if((y<y1 && y<y2) || (y>y1 && y>y2)) return kFALSE;
x = (y-y1)/(y1-y2)*(p1.getX()-p2.getX()) + p1.getX();
return kTRUE;
}
Double_t HMdcTrapPlane::calcX(Int_t ip1,Int_t ip2,Double_t y) const {
const HMdcPointPlane& p1 = points[ip1];
const HMdcPointPlane& p2 = points[ip2];
Double_t y1 = p1.getY();
Double_t y2 = p2.getY();
Double_t x1 = p1.getX();
Double_t x2 = p2.getX();
return (y-y1)/(y1-y2)*(x1-x2) + x1;
}
Bool_t HMdcTrapPlane::getXminXmax(Double_t y, Double_t& x1,Double_t& x2) {
if(y>points[yMaxPoint].getY() || y<points[yMinPoint].getY()) return kFALSE;
if(dir == 0) calcDir();
Int_t p1,p2;
for(p2 = nextXMinP(p1=yMinPoint); p2!=yMaxPoint; p2=nextXMinP(p1=p2))
if(y < points[p2].getY()) break;
x1 = calcX(p1,p2,y);
for(p2 = nextXMaxP(p1=yMinPoint); p2!=yMaxPoint; p2=nextXMaxP(p1=p2))
if(y < points[p2].getY()) break;
x2 = calcX(p1,p2,y);
return kTRUE;
}
Bool_t HMdcTrapPlane::getXminXmax(Double_t y1i,Double_t y2i,
Double_t& x1,Double_t& x2) {
if(dir == 0) calcDir();
Double_t& y1 = y1i < y2i ? y1i : y2i;
Double_t& y2 = y1i < y2i ? y2i : y1i;
if(y1>points[yMaxPoint].getY() || y2<points[yMinPoint].getY()) return kFALSE;
if(y1 <= points[yMinPoint].getY() && y2 >= points[yMaxPoint].getY()) {
x1 = points[xMinPoint].getX();
x2 = points[xMaxPoint].getX();
return kTRUE;
}
if(y2 > points[yMaxPoint].getY()) x1 = x2 = points[yMaxPoint].getX();
else {
x1 = +1.0e+20;
x2 = -1.0e+20;
}
Int_t p1 = yMinPoint;
for(Int_t p2 = nextXMinP(p1); p1!=yMaxPoint; p2=nextXMinP(p1=p2)) {
Double_t yp2 = points[p2].getY();
if(y1 > yp2) continue;
Double_t yp1 = points[p1].getY();
if(y1 >= yp1) x1 = TMath::Min(x1,calcX(p1,p2,y1));
else if(yp1<=y2 && x1>points[p1].getX()) x1 = points[p1].getX();
if(y2 > yp2) continue;
if(y2 >= yp1) x1 = TMath::Min(x1,calcX(p1,p2,y2));
break;
}
p1 = yMinPoint;
for(Int_t p2 = nextXMaxP(p1); p1!=yMaxPoint; p2=nextXMaxP(p1=p2)) {
Double_t yp2 = points[p2].getY();
if(y1 > yp2) continue;
Double_t yp1 = points[p1].getY();
if(y1 >= yp1) x2 = TMath::Max(x2,calcX(p1,p2,y1));
else if(yp1<=y2 && x2<points[p1].getX()) x2 = points[p1].getX();
if(y2 > yp2) continue;
if(y2 >= yp1) x2 = TMath::Max(x2,calcX(p1,p2,y2));
break;
}
return kTRUE;
}
void HMdcPlane::setPlanePar(const HGeomTransform& tr) {
const HGeomRotation& mt=tr.getRotMatrix();
const HGeomVector& tv=tr.getTransVector();
Double_t c=(Double_t)(mt(0)*mt(4)-mt(3)*mt(1));
if( c==0. ) return;
parA = (mt(3)*mt(7)-mt(6)*mt(4))/c;
parB = (mt(6)*mt(1)-mt(0)*mt(7))/c;
parD = parA*tv(0)+parB*tv(1)+tv(2);
}
void HMdcPlane::print() {
printf("Plane equation: %g*x%+g*y+z=%g\n",parA,parB,parD);
}
void HMdcPlane::transTo(const HGeomTransform* trans) {
HGeomVector p1( 0., 0., parD);
HGeomVector p2(parD, parD, parD*(1.-parA-parB));
HGeomVector p3(parD,-parD, parD*(1.-parA+parB));
p1 = trans->transTo(p1);
p2 = trans->transTo(p2);
p3 = trans->transTo(p3);
HGeomVector p12(p1-p2);
HGeomVector p13(p1-p3);
parB = (p12.Z()*p13.X()-p13.Z()*p12.X())/(p13.Y()*p12.X()-p12.Y()*p13.X());
if(p12.X() != 0.) parA = -(parB*p12.Y() + p12.Z())/p12.X();
else parA = -(parB*p13.Y() + p13.Z())/p13.X();
parD = parA*p1.X() + parB*p1.Y() + p1.Z();
}
void HMdcPlane::transFrom(const HGeomTransform* trans) {
HGeomVector p1( 0., 0., parD);
HGeomVector p2(parD, parD, parD*(1.-parA-parB));
HGeomVector p3(parD,-parD, parD*(1.-parA+parB));
p1 = trans->transFrom(p1);
p2 = trans->transFrom(p2);
p3 = trans->transFrom(p3);
HGeomVector p12(p1-p2);
HGeomVector p13(p1-p3);
parB = (p12.Z()*p13.X()-p13.Z()*p12.X())/(p13.Y()*p12.X()-p12.Y()*p13.X());
if(p12.X() != 0.) parA = -(parB*p12.Y() + p12.Z())/p12.X();
else parA = -(parB*p13.Y() + p13.Z())/p13.X();
parD = parA*p1.X() + parB*p1.Y() + p1.Z();
}
HMdcPointOnPlane::HMdcPointOnPlane(HMdcPlane* p) {
pl = *p;
}
HMdcPointOnPlane::HMdcPointOnPlane(HMdcPointOnPlane& p) :
HGeomVector(p.x,p.y,p.z) {
pl = p.pl;
}
void HMdcPointOnPlane::print(void) const {
printf("Point x=%7f y=%7f z=%7f on the plane %g*x%+g*y+z=%g\n",
x,y,z,pl.A(),pl.B(),pl.D());
}
void HMdcPointOnPlane::transTo(const HGeomTransform* trans) {
pl.transTo(trans);
*((HGeomVector*)this) = trans->transTo(*((HGeomVector*)this));
}
void HMdcPointOnPlane::transFrom(const HGeomTransform* trans) {
pl.transFrom(trans);
*((HGeomVector*)this) = trans->transFrom(*((HGeomVector*)this));
}
void HMdcLineParam::setCoorSys(Int_t s,Int_t m) {
if(s<-1 || s>5) {
sec = -2;
mod = -2;
} else {
sec = s;
if(sec==-1 || m<0 || m>3) mod = -1;
else mod = m;
}
}
void HMdcLineParam::setSegmentLine(Double_t r, Double_t z,
Double_t theta, Double_t phi) {
Double_t cosPhi = TMath::Cos(phi);
Double_t sinPhi = TMath::Sin(phi);
Double_t x1 = -r*sinPhi;
Double_t y1 = r*cosPhi;
Double_t dZ = TMath::Cos(theta);
Double_t dxy = TMath::Sqrt(1.-dZ*dZ)*100.;
Double_t x2 = dxy*cosPhi+x1;
Double_t y2 = dxy*sinPhi+y1;
Double_t z2 = dZ*100.+z;
point1.calcPoint(x1,y1,z,x2,y2,z2);
point2.calcPoint(x1,y1,z,x2,y2,z2);
}
Double_t HMdcLineParam::getPhiRad(void) const {
Double_t ph = TMath::ATan2(dY(),dX());
if(ph >= 0.) return ph;
return TMath::TwoPi()+ph;
}
void HMdcLineParam::transTo(const HGeomTransform* tr,Int_t s,Int_t m) {
point1.transTo(tr);
point2.transTo(tr);
calcDir();
if(sec>=-2) sec = s;
if(mod>=-2) mod = m;
}
void HMdcLineParam::transFrom(const HGeomTransform* tr,Int_t s,Int_t m) {
point1.transFrom(tr);
point2.transFrom(tr);
calcDir();
if(sec>=-2) sec = s;
if(mod>=-2) mod = m;
}
Last change: Sat May 22 13:02:34 2010
Last generated: 2010-05-22 13:02
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.