Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/ellipse is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_sg_ellipse
0005 #define tools_sg_ellipse
0006 
0007 // same logic as ROOT/TEllipse.
0008 
0009 #include "node"
0010 #include "sf"
0011 #include "render_action"
0012 #include "pick_action"
0013 #include "bbox_action"
0014 
0015 #include "../mathf"
0016 #include "../curve"
0017 
0018 namespace tools {
0019 namespace sg {
0020 
0021 class ellipse : public node,public curve {
0022   TOOLS_NODE_NO_CAST(ellipse,tools::sg::ellipse,node)
0023 public:
0024   virtual void* cast(const std::string& a_class) const {
0025     if(void* p = cmp_cast<ellipse>(this,a_class)) return p;
0026     if(void* p = cmp_cast<curve>(this,a_class)) return p;
0027     return node::cast(a_class);
0028   }
0029 public:
0030   sf<float> rx;
0031   sf<float> ry;
0032   sf<float> phi_min;  //radians
0033   sf<float> phi_max;  //radians
0034   sf<unsigned int> steps;
0035 public:
0036   virtual const desc_fields& node_desc_fields() const {
0037     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::ellipse)
0038     static const desc_fields s_v(parent::node_desc_fields(),5, //WARNING : take care of count.
0039       TOOLS_ARG_FIELD_DESC(rx),
0040       TOOLS_ARG_FIELD_DESC(ry),
0041       TOOLS_ARG_FIELD_DESC(phi_min),
0042       TOOLS_ARG_FIELD_DESC(phi_max),
0043       TOOLS_ARG_FIELD_DESC(steps)
0044     );
0045     return s_v;
0046   }
0047 private:
0048   void add_fields(){
0049     add_field(&rx);
0050     add_field(&ry);
0051     add_field(&phi_min);
0052     add_field(&phi_max);
0053     add_field(&steps);
0054   }
0055 public: //curve
0056   virtual bool pos_tan_nor(float /*a_s*/,
0057                            vec3f& a_pos,
0058                            vec3f& a_tan,
0059                            vec3f& a_nor) const {
0060 
0061     //float r = radius.value();
0062     //float cs = fcos(a_s);
0063     //float sn = fsin(a_s);
0064 
0065     float x,y,z;
0066 
0067    {//x = r*cs;y = r*sn;z = 0;
0068     x = 0;y = 0;z = 0;
0069     m_model.mul_3f(x,y,z);
0070     a_pos.set_value(x,y,z);}
0071 
0072    {//x = -sn;y = cs;z = 0;
0073     x = 0;y = 1;z = 0;
0074     m_model.mul_dir_3(x,y,z);
0075     a_tan.set_value(x,y,z);}
0076 
0077    {x = 0;y = 0;z = 1;
0078     m_model.mul_dir_3(x,y,z);
0079     a_nor.set_value(x,y,z);}
0080 
0081     return true;
0082   }
0083 public:
0084   virtual void copy(curve*& a_new) const {a_new = new ellipse(*this);}
0085 public:
0086   virtual void render(render_action& a_action) {
0087     if(touched()) {
0088       update_sg();
0089       reset_touched();
0090     }
0091     //Same logic as Inventor SoLightModel.model = BASE_COLOR.
0092     const state& state = a_action.state();
0093     a_action.set_lighting(false);
0094     a_action.add_line_strip(m_xyzs);
0095     a_action.set_lighting(state.m_GL_LIGHTING);
0096   }
0097 
0098   virtual void pick(pick_action& a_action) {
0099     if(touched()) {
0100       update_sg();
0101       reset_touched();
0102     }
0103     if(a_action.stop_at_first()){
0104       a_action.add_line_strip(m_xyzs);
0105       if(a_action.done()) a_action.set_node(this);
0106     } else {
0107       a_action.set_done(false);
0108       a_action.zs().clear();
0109       a_action.ws().clear();
0110       a_action.add_line_strip(m_xyzs);
0111       if(a_action.done()) {
0112         a_action.add_pick(*this,a_action.zs(),a_action.ws(),a_action.state());
0113         a_action.set_done(false);
0114       }
0115     }
0116   }
0117   virtual void bbox(bbox_action& a_action) {
0118     if(touched()) {
0119       update_sg();
0120       reset_touched();
0121     }
0122     a_action.add_line_strip(m_xyzs);
0123   }
0124 public:
0125   ellipse()
0126   :parent()
0127   ,curve()
0128   ,rx(1)
0129   ,ry(1)
0130   ,phi_min(0)
0131   ,phi_max(tools::ftwo_pi())
0132   ,steps(40)
0133   {
0134     add_fields();
0135   }
0136   virtual ~ellipse(){}
0137 public:
0138   ellipse(const ellipse& a_from)
0139   :parent(a_from)
0140   ,curve(a_from)
0141   ,rx(a_from.rx)
0142   ,ry(a_from.ry)
0143   ,phi_min(a_from.phi_min)
0144   ,phi_max(a_from.phi_max)
0145   ,steps(a_from.steps)
0146   {
0147     add_fields();
0148   }
0149   ellipse& operator=(const ellipse& a_from){
0150     parent::operator=(a_from);
0151     curve::operator=(a_from);
0152     rx = a_from.rx;
0153     ry = a_from.ry;
0154     phi_min = a_from.phi_min;
0155     phi_max = a_from.phi_max;
0156     steps = a_from.steps;
0157     return *this;
0158   }
0159 protected:
0160   void update_sg() {
0161     m_xyzs.clear();
0162     if(!steps.value()) return;
0163 
0164     unsigned int num = steps.value();
0165 
0166    //set number of points approximatively proportional to the ellipse circumference
0167    //float circ = kPI*(r1+r2)*(phi2-phi1)/360;
0168    //Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1())));
0169    //if (n < 8) n= 8;
0170    //if (n > np) n = np;
0171 
0172     m_xyzs.resize((num+1)*3);
0173 
0174     float phimin = phi_min.value();
0175     float phimax = phi_max.value();
0176     float r1 = rx.value();
0177     float r2 = ry.value();
0178 
0179     float phi1 = mn<float>(phimin,phimax);
0180     float phi2 = mx<float>(phimin,phimax);
0181 
0182     float angle,dx,dy;
0183     float dphi = (phi2-phi1)/float(num);
0184     size_t pos = 0;
0185     for(unsigned int i=0;i<=num;i++) {
0186       angle = phi1 + float(i)*dphi;
0187       dx    = r1*fcos(angle);
0188       dy    = r2*fsin(angle);
0189       m_xyzs[pos]  = dx;pos++;
0190       m_xyzs[pos]  = dy;pos++;
0191       m_xyzs[pos]  = 0;pos++;
0192     }
0193     /*
0194     TString opt = option;
0195     opt.ToLower();
0196     if (phi2-phi1 >= 360 ) {
0197       if (GetFillStyle()) gPad->PaintFillArea(n,x,y);
0198       if (GetLineStyle()) gPad->PaintPolyLine(n+1,x,y);
0199     } else {
0200       x[n+1] = gPad->XtoPad(x1);
0201       y[n+1] = gPad->YtoPad(y1);
0202       x[n+2] = x[0];
0203       y[n+2] = y[0];
0204       if (GetFillStyle()) gPad->PaintFillArea(n+2,x,y);
0205       if (GetLineStyle()) {
0206          if (TestBit(kNoEdges) || opt.Contains("only")) gPad->PaintPolyLine(n+1,x,y);
0207          else                                           gPad->PaintPolyLine(n+3,x,y);
0208       }
0209     }
0210     */
0211 
0212   }
0213 
0214 protected:
0215   std::vector<float> m_xyzs;
0216 };
0217 
0218 }}
0219 
0220 #endif