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 x,y,z;
0062
0063 {//x = r*cs;y = r*sn;z = 0;
0064 x = 0;y = 0;z = 0;
0065 m_model.mul_3f(x,y,z);
0066 a_pos.set_value(x,y,z);}
0067
0068 {//x = -sn;y = cs;z = 0;
0069 x = 0;y = 1;z = 0;
0070 m_model.mul_dir_3(x,y,z);
0071 a_tan.set_value(x,y,z);}
0072
0073 {x = 0;y = 0;z = 1;
0074 m_model.mul_dir_3(x,y,z);
0075 a_nor.set_value(x,y,z);}
0076
0077 return true;
0078 }
0079 public:
0080 virtual void copy(curve*& a_new) const {a_new = new ellipse(*this);}
0081 public:
0082 virtual void render(render_action& a_action) {
0083 if(touched()) {
0084 update_sg();
0085 reset_touched();
0086 }
0087 //Same logic as Inventor SoLightModel.model = BASE_COLOR.
0088 const state& state = a_action.state();
0089 a_action.set_lighting(false);
0090 a_action.add_line_strip(m_xyzs);
0091 a_action.set_lighting(state.m_GL_LIGHTING);
0092 }
0093
0094 virtual void pick(pick_action& a_action) {
0095 if(touched()) {
0096 update_sg();
0097 reset_touched();
0098 }
0099 if(a_action.stop_at_first()){
0100 a_action.add_line_strip(m_xyzs);
0101 if(a_action.done()) a_action.set_node(this);
0102 } else {
0103 a_action.set_done(false);
0104 a_action.zs().clear();
0105 a_action.ws().clear();
0106 a_action.add_line_strip(m_xyzs);
0107 if(a_action.done()) {
0108 a_action.add_pick(*this,a_action.zs(),a_action.ws(),a_action.state());
0109 a_action.set_done(false);
0110 }
0111 }
0112 }
0113 virtual void bbox(bbox_action& a_action) {
0114 if(touched()) {
0115 update_sg();
0116 reset_touched();
0117 }
0118 a_action.add_line_strip(m_xyzs);
0119 }
0120 public:
0121 ellipse()
0122 :parent()
0123 ,curve()
0124 ,rx(1)
0125 ,ry(1)
0126 ,phi_min(0)
0127 ,phi_max(tools::ftwo_pi())
0128 ,steps(40)
0129 {
0130 add_fields();
0131 }
0132 virtual ~ellipse(){}
0133 public:
0134 ellipse(const ellipse& a_from)
0135 :parent(a_from)
0136 ,curve(a_from)
0137 ,rx(a_from.rx)
0138 ,ry(a_from.ry)
0139 ,phi_min(a_from.phi_min)
0140 ,phi_max(a_from.phi_max)
0141 ,steps(a_from.steps)
0142 {
0143 add_fields();
0144 }
0145 ellipse& operator=(const ellipse& a_from){
0146 parent::operator=(a_from);
0147 curve::operator=(a_from);
0148 rx = a_from.rx;
0149 ry = a_from.ry;
0150 phi_min = a_from.phi_min;
0151 phi_max = a_from.phi_max;
0152 steps = a_from.steps;
0153 return *this;
0154 }
0155 protected:
0156 void update_sg() {
0157 m_xyzs.clear();
0158 if(!steps.value()) return;
0159
0160 unsigned int num = steps.value();
0161
0162 //set number of points approximatively proportional to the ellipse circumference
0163 //float circ = kPI*(r1+r2)*(phi2-phi1)/360;
0164 //Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1())));
0165 //if (n < 8) n= 8;
0166 //if (n > np) n = np;
0167
0168 m_xyzs.resize((num+1)*3);
0169
0170 float phimin = phi_min.value();
0171 float phimax = phi_max.value();
0172 float r1 = rx.value();
0173 float r2 = ry.value();
0174
0175 float phi1 = min_of<float>(phimin,phimax);
0176 float phi2 = max_of<float>(phimin,phimax);
0177
0178 float angle,dx,dy;
0179 float dphi = (phi2-phi1)/float(num);
0180 size_t pos = 0;
0181 for(unsigned int i=0;i<=num;i++) {
0182 angle = phi1 + float(i)*dphi;
0183 dx = r1*fcos(angle);
0184 dy = r2*fsin(angle);
0185 m_xyzs[pos] = dx;pos++;
0186 m_xyzs[pos] = dy;pos++;
0187 m_xyzs[pos] = 0;pos++;
0188 }
0189 }
0190
0191 protected:
0192 std::vector<float> m_xyzs;
0193 };
0194
0195 }}
0196
0197 #endif