00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __potential_hpp__
00022 #define __potential_hpp__
00023
00024 #include <list>
00025 #include <string>
00026 #include <vector>
00027
00028 class PField;
00029 class PLink;
00030
00031 class PPoint
00032 {
00033 public:
00034 PPoint (const vect3d& pos, const vect3d& ppos = vect3d(0, 0, 0), prec_t potential = 0);
00035
00036 const vect3d& get_pos () const { return pos; }
00037
00038 private:
00039 typedef std::list<PLink*> links_t;
00040 links_t links;
00041
00042 size_t id;
00043 vect3d pos, pot_pos;
00044 prec_t potential;
00045 prec_t charge;
00046 prec_t rho;
00047 enum eflags { NO_CDIST = 1 };
00048 size_t flags;
00049
00050 vect3d cur_efield;
00051 prec_t inc;
00052
00053 void step() { charge += inc; inc = 0; }
00054
00055 friend class PField;
00056 friend class PLink;
00057 friend class StaticPotentialField;
00058 };
00059
00060 class PLink
00061 {
00062 public:
00063 PLink(PPoint *a, PPoint *b) : a(a), b(b), q(0)
00064 {
00065 ab = b->pos - a->pos;
00066 ab_normal = ab.normal();
00067 rr = ab*ab;
00068 len = prec_t_sqrt (rr);
00069 mid = 0.5 * (a->pos + b->pos);
00070 cc_normal = (0.05 * rr) * ab_normal;
00071 abr = (1 / (ab * ab)) * ab;
00072 rhodiff_by_llen = (b->rho - a->rho) / len;
00073 }
00074
00075 private:
00076 PPoint *a, *b;
00077 vect3d ab;
00078 vect3d ab_normal;
00079 vect3d abr;
00080 vect3d cc_normal;
00081 prec_t rr;
00082 prec_t len;
00083 vect3d mid;
00084 prec_t rhodiff_by_llen;
00085
00086 prec_t q;
00087 vect3d efield;
00088 PPoint *tmp;
00089
00090 friend class PField;
00091 friend class PPoint;
00092 friend class StaticPotentialField;
00093 };
00094
00095 class StaticPotentialField;
00096
00097 class PField
00098 {
00099 public:
00100 enum emethod_t { POINTSYSTEM = 1, CHARGEFLOW, LINESYSTEM };
00101
00102 #define UNKNOWN_POTENTIAL 9e99
00103
00104 PField (emethod_t method = POINTSYSTEM, prec_t resolution = 0.02);
00105 ~PField ();
00106
00107 PPoint& addPoint (const vect3d& pos, const vect3d& ppos = vect3d(0, 0, 0), prec_t potential = 0);
00108 void addFeedPoint (PPoint& p, prec_t potential);
00109
00110 void addSphere (const vect3d& p, prec_t radius, prec_t potential = 0, bool backawrds = false);
00111 void addTorus (const vect3d& p, const vect3d& normal, prec_t radius, prec_t wr, prec_t potential = 0);
00112 void addStrip (const vect3d& p0, const vect3d& p1, size_t n_segments = 0);
00113 void addT (const vect3d& p0, const vect3d& p1, const vect3d& p2, const vect3d& p3);
00114
00115 bool equalize();
00116
00117 std::string getPovrayScript ();
00118 std::string getChargeConcentrationScript ();
00119
00120 void getEfield(const vect3d& pos, vect3d& efield);
00121 prec_t getPotential(const vect3d& pos);
00122
00123 void setPointCharge (const vect3d& pos, prec_t q);
00124 void setUniformCharge (const vect3d& pos, prec_t q, prec_t radius);
00125
00126 PLink& connect (PPoint& a, PPoint& b);
00127 PLink* safe_connect (PPoint& a, PPoint& b);
00128 PLink& split (PLink& link, PPoint& mid);
00129
00130 void print();
00131
00132 prec_t getAddedCharge () const { return added_charge; }
00133 prec_t getAveragePotential();
00134 void setPotential (prec_t pot);
00135
00136 void save (const char *path);
00137 void save (const std::string& path) { save (path.c_str()); }
00138 bool load (const char *path);
00139 bool load (const std::string& path) { return load (path.c_str()); }
00140
00141 void set_no_cdist (bool ncd) { no_cdist = ncd; }
00142
00143 void getStatistics (size_t& pointcount, size_t& linkcount) { pointcount = points.size(); linkcount = links.size(); }
00144
00145 prec_t getResolution() const { return resolution; }
00146 prec_t setResolution(prec_t res) { prec_t ores = resolution; resolution = res; return ores; }
00147
00148 private:
00149 emethod_t method;
00150 prec_t resolution;
00151 size_t pcounter;
00152 bool no_cdist;
00153
00154 typedef std::list<PPoint> points_t;
00155 points_t points;
00156
00157 struct fpoint_t
00158 {
00159 fpoint_t() : cp(0), q(0) { }
00160 PPoint *point;
00161 prec_t potential;
00162 prec_t cp;
00163 prec_t q;
00164 };
00165
00166 typedef std::list<fpoint_t> feeds_t;
00167 feeds_t feeds;
00168
00169 prec_t added_charge;
00170
00171 prec_t pc_q;
00172 vect3d pc_pos;
00173 prec_t pc_radius;
00174 prec_t pc_rr;
00175 prec_t pc_rho;
00176
00177 typedef std::list<PLink> links_t;
00178 links_t links;
00179
00180 struct task : Task
00181 {
00182 PField *pf;
00183 links_t::iterator begin;
00184 links_t::iterator end;
00185 vect3d *cache;
00186 void execute () { pf->calc_efield (begin, end, cache); }
00187 };
00188
00189 void calc_efield (const links_t::iterator& begin, const links_t::iterator& end, const vect3d* cache);
00190 bool equalize_chargeflow();
00191 bool equalize_pointsystem();
00192 bool equalize_linesystem();
00193
00194 vect3d * cache;
00195
00196 friend class StaticPotentialField;
00197 };
00198
00199 class StaticPotentialField : public StaticElement
00200 {
00201 public:
00202 StaticPotentialField (PField &pfield) : pfield(pfield) { }
00203
00204 void addFields (const vect3d& pos, vect3d& bfield, vect3d& efield);
00205 void addPotential (const vect3d& pos, prec_t& potential);
00206 void draw(Screen& screen, const Screen::color& c = Screen::BLACK);
00207 std::string get_povray_script ();
00208 bool inContact (const vect3d& pos);
00209
00210 private:
00211 PField& pfield;
00212 };
00213
00214 #endif // !__potential_hpp__
00215