#ifndef X_SPLINE
#define X_SPLINE
#include "TObject.h"
#include "TGraph.h"
#include "TArrayD.h"
#include "TArrayF.h"
#include "TArrow.h"
#include "TList.h"
#include "TMarker.h"
#include "TObjArray.h"
#include "TPolyLine.h"
#include "TStyle.h"
#include "TVirtualPad.h"
#include "Buttons.h"
#include "HprText.h"
#include <iostream>
class TOrdCollection;
class TSplineX;
class PolyLineNoEdit: public TPolyLine {
public:
PolyLineNoEdit(){};
PolyLineNoEdit(Int_t np, Double_t * x = NULL, Double_t * y = NULL);
virtual ~PolyLineNoEdit() {};
Int_t DistancetoPrimitive(Int_t, Int_t){return 9999;};
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,12,0)
void SavePrimitive(std::ostream &, Option_t *){};
#else
void SavePrimitive(std::ofstream &, Option_t *){};
#endif
ClassDef(PolyLineNoEdit,0)
};
class RailwaySleeper : public TPolyLine {
private:
TSplineX * fParent;
public:
RailwaySleeper(){};
RailwaySleeper(Double_t * x, Double_t * y, TSplineX * parent = NULL,
Color_t color = 1);
~RailwaySleeper(){ };
Int_t DistancetoPrimitive(Int_t, Int_t){return 9999;};
void ExecuteEvent(Int_t event, Int_t px, Int_t py);
void Draw(Option_t * opt = "F");
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,12,0)
void SavePrimitive(std::ostream &, Option_t *){};
#else
void SavePrimitive(std::ofstream &, Option_t *){};
#endif
ClassDef(RailwaySleeper,0)
};
class ControlGraph : public TGraph
{
friend class TSplineX;
private:
TSplineX *fParent;
TArrayF fShapeFactors;
Int_t fSelectedPoint;
Double_t fSelectedX;
Double_t fSelectedY;
Float_t fSelectedShapeFactor;
TArrayI fMixerValues;
TArrayI fMixerMinval;
TArrayI fMixerMaxval;
TArrayI fMixerFlags;
TOrdCollection *fRowlab;
protected:
virtual ~ControlGraph() {};
public:
ControlGraph (Int_t npoints = 0, Double_t* x = NULL, Double_t* y = NULL);
virtual void Delete(Option_t *) { std::cout << " no no " << std::endl; };
int DistancetoPrimitive(Int_t px, Int_t py);
void ExecuteEvent(Int_t event, Int_t px, Int_t py);
void SetParent(TSplineX* parent);
TSplineX *GetParent(){return fParent;};
void SetLength(Int_t npoints) {Set(npoints);fShapeFactors.Set(npoints);};
void SetAllShapeFactors(Int_t npoints, Float_t* sf);
Float_t GetShapeFactor(Int_t ipoint) {return fShapeFactors[ipoint];};
Int_t GetSelectedPoint() { return fSelectedPoint; };
Double_t GetSelectedX() { return fSelectedX; };
Double_t GetSelectedY() { return fSelectedY; };
Float_t GetSelectedShapeFactor(){ return fSelectedShapeFactor;};
void SetShapeFactor(Int_t ipoint, Int_t f100);
void SetOneShapeFactor(Int_t ipoint, Double_t x, Double_t y, Float_t sfactor);
void SetControlPoint(Int_t ipoint, Double_t x, Double_t y, Float_t sfactor);
void GetControlPoint(Int_t ipoint, Double_t *x, Double_t *y, Float_t *sfactor);
Int_t InsertPoint();
Int_t RemovePoint();
Int_t RemovePoint(Int_t ip) {return ip;};
virtual void ControlGraphMixer();
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,12,0)
void SavePrimitive(std::ostream &, Option_t *){};
#else
void SavePrimitive(std::ofstream &, Option_t *){};
#endif
ClassDef(ControlGraph, 1)
};
class ParallelGraph : public TPolyLine
{
private:
TSplineX* fParent;
ParallelGraph* fSlave;
Double_t fDistToSlave;
ParallelGraph* fMaster;
Double_t fDist;
Bool_t fClosed;
Bool_t fIsRail;
public:
ParallelGraph ();
ParallelGraph (TSplineX *parent, Double_t dist, Bool_t closed);
virtual ~ParallelGraph();
void Compute();
void SetIsClosed(Bool_t cl) { fClosed = cl; };
Bool_t GetIsClosed() { return fClosed; };
void Paint(Option_t * option = " ");
Int_t DistancetoPrimitive(Int_t px, Int_t py);
void Pop();
void ExecuteEvent(Int_t event, Int_t px, Int_t py);
TSplineX *GetParent(){return fParent;};
Double_t GetDist(){return fDist;};
void SetDist(Double_t d){fDist = d;};
void Remove(Option_t * opt);
void Delete(Option_t * opt) {this->Remove(opt);};
void FillToSlave(Double_t dist = 0);
void ClearFillToSlave();
void SetSlave(ParallelGraph* slave) {fSlave = slave;};
void SetMaster(ParallelGraph* master) {fMaster = master;};
Double_t GetDistToSlave() {return fDistToSlave;};
void SetDistToSlave(Double_t d) {fDistToSlave = d;};
ParallelGraph* GetSlave() {return fSlave;};
ParallelGraph* GetMaster() {return fMaster;};
Bool_t GetIsRail() {return fIsRail;};
void SetIsRail(Bool_t israil = kTRUE) {fIsRail = israil;};
void CorrectForArrows(Double_t rxy, Double_t alen,Double_t aangle, Double_t aind_angle,
Bool_t at_start, Bool_t at_end);
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,12,0)
void SavePrimitive(std::ostream &, Option_t *){};
#else
void SavePrimitive(std::ofstream &, Option_t *){};
#endif
ClassDef(ParallelGraph, 1)
};
class ShapeFactor
{
public:
Float_t s;
ShapeFactor* next;
ShapeFactor (Float_t f, ShapeFactor* nf) { s = f;
next = nf;
};
~ShapeFactor() {};
void SetNext(ShapeFactor * nf) {
next = nf;
}
ShapeFactor* GetNext() {return next;};
};
class ControlPoint
{
public:
Double_t x, y;
ControlPoint* next;
ControlPoint (Double_t xv, Double_t yv, ControlPoint* np) {
x = xv;
y = yv;
next = np;
};
~ControlPoint() {};
void SetNext(ControlPoint * np) {
next = np;
}
ControlPoint* GetNext() {return next;};
};
class TSplineX : public TPolyLine
{
friend class ControlGraph;
friend class ParallelGraph;
friend class HandleMenus;
private:
ShapeFactor* fShapeFactorList;
ControlPoint* fControlPointList;
Int_t fNofControlPoints;
Int_t fNpoints;
Bool_t fComputeDone;
TArrayD fX;
TArrayD fY;
ControlGraph fCPGraph;
Bool_t fCPDrawn;
Style_t fMStyle;
Size_t fMSize;
ParallelGraph *fRailL;
ParallelGraph *fRailR;
TObjArray fPGraphs;
PolyLineNoEdit *fArrowAtStart;
PolyLineNoEdit *fArrowAtEnd;
TList fDPolyLines;
Double_t fCornersX[3][3];
Double_t fCornersY[3][3];
Float_t fPrec;
Bool_t fClosed;
Int_t fRailwaylike;
Double_t fRailwayGage;
Double_t fFilledLength;
Double_t fEmptyLength;
Style_t fLineStyle;
Width_t fLineWidth;
Color_t fLineColor;
Int_t fParallelFill;
Bool_t fPaintArrowAtStart;
Bool_t fPaintArrowAtEnd;
Int_t fArrowFill;
Double_t fArrowLength;
Double_t fArrowAngle;
Double_t fArrowIndentAngle;
Double_t fRatioXY;
TList *fTextList;
Double_t f_blend(Double_t numerator, Double_t denominator);
Double_t g_blend(Double_t u, Double_t q);
Double_t h_blend(Double_t u, Double_t q);
void negative_s1_influence(Double_t t, Double_t s1, Double_t *A0, Double_t *A2);
void negative_s2_influence(Double_t t, Double_t s2, Double_t *A1, Double_t *A3);
void positive_s1_influence(Int_t k, Double_t t, Double_t s1, Double_t *A0, Double_t *A2);
void positive_s2_influence(Int_t k, Double_t t, Double_t s2, Double_t *A1, Double_t *A3);
void point_computing(Double_t *A_blend, ControlPoint *p0, ControlPoint *p1,
ControlPoint *p2, ControlPoint *p3, Double_t *xs, Double_t *ys);
void point_adding(Double_t *A_blend, ControlPoint *p0, ControlPoint *p1,
ControlPoint *p2, ControlPoint *p3);
Float_t step_computing(int k, ControlPoint *p0, ControlPoint *p1,
ControlPoint *p2, ControlPoint *p3,
Double_t s1, Double_t s2, Float_t precision);
void spline_segment_computing(Float_t step, Int_t k,
ControlPoint *p0, ControlPoint *p1,
ControlPoint *p2, ControlPoint *p3,
Double_t s1, Double_t s2);
Int_t op_spline(ControlPoint *cpoints, ShapeFactor *sfactors, Float_t precision);
Int_t cl_spline(ControlPoint *cpoints, ShapeFactor *sfactors, Float_t precision);
Int_t add_point(Double_t x, Double_t y);
Int_t add_closepoint();
void too_many_points();
void Delete_ShapeFactors();
void Delete_ControlPoints();
void SetGraph();
void CopyControlPoints();
protected:
Int_t ComputeSpline();
Double_t Length(Double_t x1, Double_t y1, Double_t x2, Double_t y2);
Double_t PhiOfLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2);
void Nextpoint(Double_t phi, Double_t x, Double_t y,
Double_t dist, Double_t* a, Double_t* b);
void Endpoint(Double_t phi, Double_t x, Double_t y,
Double_t dist, Double_t* a, Double_t* b);
void Midpoint(Double_t phi1, Double_t phi2, Double_t x, Double_t y,
Double_t dist ,Double_t* a, Double_t* b);
Double_t GetArrowLength(Double_t dist,Double_t al,Double_t aa, Double_t aia);
public:
TSplineX();
TSplineX(Int_t npoints, Double_t *x = NULL, Double_t *y = NULL,
Float_t *sf = NULL, Float_t prec = 0.2, Bool_t closed = kFALSE);
virtual ~TSplineX();
Int_t DistancetoPrimitive(Int_t px, Int_t py);
void ExecuteEvent(Int_t event, Int_t px, Int_t py);
void Pop();
Int_t InsertPoint() {return fCPGraph.InsertPoint();};
Int_t RemovePoint() {return fCPGraph.RemovePoint();};
void RemovePolyLines();
void ControlGraphMixer(){fCPGraph.ControlGraphMixer();};
void Print(Option_t *) const;
void DrawControlPoints(Style_t marker = 24, Size_t size = 1);
void RemoveControlPoints();
Style_t GetMStyle() {return fMStyle;};
Size_t GetMSize() {return fMSize;};
void SetMStyle(Style_t type) {fMStyle = type;};
void SetMSize(Size_t size) {fMSize = size;};
void SetAllControlPoints(Int_t npoints, Double_t* x, Double_t* y);
void SetControlPoint(Int_t ip, Double_t x, Double_t y, Float_t sf)
{fCPGraph.SetControlPoint(ip, x, y, sf);};
void GetControlPoint(Int_t ip, Double_t *x, Double_t *y, Float_t *sf)
{fCPGraph.GetControlPoint(ip, x, y, sf);};
void SetShapeFactors(Int_t npoints, Float_t* sf);
Int_t GetNofControlPoints() {return fCPGraph.GetN();};
Bool_t GetCPDrawn() {return fCPDrawn;};
Int_t GetResult(Double_t*& x, Double_t*& y);
void SetIsClosed(Bool_t isclosed = kTRUE);
Bool_t GetIsClosed() {return fClosed;};
ControlGraph* GetControlGraph() {return &fCPGraph;};
TList* GetDPolyLines() {return &fDPolyLines;};
void Paint(Option_t * option = " ");
void PaintArrow(Int_t where);
void DrawParallelGraphs();
ParallelGraph* AddParallelGraph(Double_t dist = 2, Color_t color=0,
Width_t width=0, Style_t style=0);
TObjArray* GetParallelGraphs() {return &fPGraphs;};
void SetRailwaylike (Double_t gage = 4);
Int_t IsRailwaylike() {return fRailwaylike;};
void SetRailwayGage (Double_t gage) {SetRailwaylike(gage);};
Double_t GetRailwayGage () {return fRailwayGage;};
void SetFilledLength(Double_t flen) {fFilledLength = flen;};
void SetEmptyLength(Double_t elen) {fEmptyLength = elen;};
Double_t GetFilledLength() {return fFilledLength;};
Double_t GetEmptyLength() {return fEmptyLength;};
void NeedReCompute() {fComputeDone = kFALSE;};
void SetSleeperColor(Color_t color);
Int_t GetParallelFill() {return fParallelFill;};
void SetParallelFill(Int_t sf) {fParallelFill = sf;};
void AddArrow(Int_t where = 1, Double_t size = 10, Double_t angle = 30,
Double_t indent_angle = 0, Int_t filled = 0);
void SetArrowLength(Double_t length) {fArrowLength = length;};
void SetArrowAngle(Double_t angle) {fArrowAngle = angle;};
void SetArrowIndentAngle(Double_t a) {fArrowIndentAngle = a;};
Double_t GetArrowLength() {return fArrowLength;};
Double_t GetArrowAngle() {return fArrowAngle;};
Double_t GetArrowIndentAngle() {return fArrowIndentAngle;};
void SetPaintArrowAtStart(Bool_t ok) {fPaintArrowAtStart = ok;};
void SetPaintArrowAtEnd(Bool_t ok) {fPaintArrowAtEnd = ok;};
Bool_t GetPaintArrowAtStart() {return fPaintArrowAtStart;};
Bool_t GetPaintArrowAtEnd() {return fPaintArrowAtEnd;};
Int_t GetArrowFill() {return fArrowFill;};
void SetArrowFill(Bool_t filled);
void AddText(TObject *hprtext);
TList *GetTextList() {return fTextList;};
void PaintText();
Double_t GetLengthOfText(HprText *t, Double_t csep, Int_t start, Int_t end, Int_t step, Double_t s0);
Double_t GetLengthOfSpline();
Double_t GetPhiXY(Double_t s, Double_t &x, Double_t &y);
Double_t *GetCornersX() {return &fCornersX[0][0]; }
Double_t *GetCornersY() {return &fCornersY[0][0]; }
void PrintAddress(){std::cout << "TSplineX *sp = (TSplineX*)" << this << std::endl;}
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,12,0)
void SavePrimitive(std::ostream &, Option_t *);
#else
void SavePrimitive(std::ofstream &, Option_t *);
#endif
void CRButtonPressed(Int_t, Int_t){};
ClassDef(TSplineX, 2)
};
#endif