#include "hparamlist.h"
#include "hrichframe.h"
#include "hrichframecorner.h"
#include <iostream>
#include <cstdlib>
using namespace std;
ClassImp(HRichFrame)
HRichFrame::HRichFrame()
: TObject()
{
clear();
}
HRichFrame::~HRichFrame()
{
clear();
}
void
HRichFrame::clear()
{
fCornerNr = 0;
fFrameArr.Delete();
}
Bool_t
HRichFrame::getParams(HParamList* l)
{
HRichFrameCorner *pFrameCorner = NULL;
if (!l) return kFALSE;
if (!l->fill("fFrameCorners", &fFrameCorners)) return kFALSE;
for (Int_t i = 0; i < fFrameCorners.GetSize() / 2; ++i) {
pFrameCorner = new HRichFrameCorner;
pFrameCorner->setX(fFrameCorners[2*i]);
pFrameCorner->setY(fFrameCorners[2*i+1]);
pFrameCorner->setCornerNr(i);
addCorner(pFrameCorner);
}
return calculateFlagArea();
}
void
HRichFrame::printParams()
{
if (fFrameArr.GetSize() < getCornerNr() || getCornerNr() != 7) {
Error("printParams", "Inconsistency in number of frame corners (%d < %d)", fFrameArr.GetSize(), getCornerNr());
return;
}
cout << "HRichFrame" << endl;
cout << "==========================================" << endl;
cout << "fFrameCorners " << endl;
for (Int_t i = 0; i < getCornerNr(); ++i) {
cout << getCorner(i)->getX() << " "
<< getCorner(i)->getY() << " " << endl;
}
cout << endl;
}
void
HRichFrame::putParams(HParamList* l)
{
if (!l) return;
l->add("fFrameCorners", fFrameCorners);
}
HRichFrameCorner*
HRichFrame::getCorner(Int_t n)
{
if ((n < 0) || (n >= getCornerNr())) {
return NULL;
}
return static_cast<HRichFrameCorner*>(fFrameArr.At(n));
}
Int_t
HRichFrame::setCorner(HRichFrameCorner* pCorner, Int_t n)
{
if ((n < 0) || (n >= getCornerNr())) {
return 0;
}
delete fFrameArr.At(n);
fFrameArr.AddAt(pCorner, n);
return 1;
}
Int_t
HRichFrame::addCorner(HRichFrameCorner* pCorner)
{
fFrameArr.Add(pCorner);
return fCornerNr++;
}
Int_t
HRichFrame::isOut(Float_t x, Float_t y)
{
Int_t nCornerNr = getCornerNr();
if (nCornerNr <= 2) {
Error("isOut", "Frame must have at least 3 corners!");
return -1;
}
#ifdef RICHDIGI_DEBUG3
cout << "RICHDIGI: HRichFrame _isOut_ is now calculated \n";
#endif
Float_t X0 = 0.;
Float_t X1 = 0.;
Float_t Y0 = 0.;
Float_t Y1 = 0.;
Float_t a = 0.;
Float_t b = 0.;
Int_t nFlag = 0;
for (Int_t i = 0; i < nCornerNr; i++) {
getCorner(i)->getXY(&X0, &Y0);
nFlag = getCorner(i)->getFlagArea();
if (i + 1 < nCornerNr) {
getCorner(i + 1)->getXY(&X1, &Y1);
} else {
getCorner(0)->getXY(&X1, &Y1);
}
if (X0 == X1) {
if (nFlag == 0 && x > X0) return 1;
else if (nFlag == 1 && x < X0) return 1;
} else if (Y0 == Y1) {
if (nFlag == 0 && y > Y0) return 1;
else if (nFlag == 1 && y < Y0) return 1;
} else {
a = (Y1 - Y0) / (X1 - X0);
b = (X1 * Y0 - X0 * Y1) / (X1 - X0);
if (nFlag == 0 && y > (a * x + b)) return 1;
else if (nFlag == 1 && y < (a * x + b)) return 1;
}
}
return 0;
}
Bool_t
HRichFrame::calculateFlagArea()
{
Int_t fArea0;
Int_t fArea1;
Int_t nrcor1;
Int_t nrcor2;
Float_t a;
Float_t b;
Float_t xcor1;
Float_t xcor2;
Float_t ycor1;
Float_t ycor2;
for (Int_t i = 0; i < getCornerNr(); i++) {
getCorner(i)->getXY(&xcor1, &ycor1);
nrcor1 = getCorner(i)->getCornerNr();
if (i + 1 < getCornerNr()) {
getCorner(i + 1)->getXY(&xcor2, &ycor2);
nrcor2 = getCorner(i + 1)->getCornerNr();
} else {
getCorner(0)->getXY(&xcor2, &ycor2);
nrcor2 = getCorner(0)->getCornerNr();
}
fArea0 = 0;
fArea1 = 0;
if (xcor1 == xcor2) {
for (Int_t j = 0; j < getCornerNr(); j++) {
if (getCorner(j)->getCornerNr() != nrcor1 &&
getCorner(j)->getCornerNr() != nrcor2) {
if (getCorner(j)->getX() > xcor1) fArea1++;
if (getCorner(j)->getX() < xcor1) fArea0++;
}
}
if (fArea1 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(1);
} else if (fArea0 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(0);
} else {
Error("calculateFlagArea", "Inconsistency in frame corners coordinates.");
return kFALSE;
}
} else if (ycor1 == ycor2) {
for (Int_t j = 0; j < getCornerNr(); j++) {
if (getCorner(j)->getCornerNr() != nrcor1 &&
getCorner(j)->getCornerNr() != nrcor2) {
if (getCorner(j)->getY() > ycor1) fArea1++;
if (getCorner(j)->getY() < ycor1) fArea0++;
}
}
if (fArea1 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(1);
} else if (fArea0 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(0);
} else {
Error("calculateFlagArea", "Inconsistency in frame corners coordinates.");
return kFALSE;
}
} else {
a = (ycor2 - ycor1) / (xcor2 - xcor1);
b = (xcor2 * ycor1 - xcor1 * ycor2) / (xcor2 - xcor1);
for (Int_t j = 0; j < getCornerNr(); j++) {
if (getCorner(j)->getCornerNr() != nrcor1 &&
getCorner(j)->getCornerNr() != nrcor2) {
if (getCorner(j)->getY() > a * getCorner(j)->getX() + b) fArea1++;
if (getCorner(j)->getY() < a * getCorner(j)->getX() + b) fArea0++;
}
}
if (fArea1 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(1);
} else if (fArea0 + 2 == getCornerNr()) {
getCorner(i)->setFlagArea(0);
} else {
Error("calculateFlagArea", "Inconsistency in frame corners coordinates.");
return kFALSE;
}
}
}
return kTRUE;
}