/* -*-ePiX-*- */ #include "epix.h" using namespace ePiX; // number of field lines per charge const int N(13); // charge magnitudes and locations const int charge1(1); const int charge2(1); const P Q1( 1,0); const P Q2(-1,0); // inverse-square electric field from a point charge at the origin P unit_charge(const P& arg) { return recip(arg|arg)*arg; } // electric field simulated by superimposing individual fields, then // re-scaling so that field -> 0 near the charge location (improves // plot quality:) P E(double x, double y) { P temp(x,y); // superposition of charge fields P E_temp(charge1*unit_charge(temp-Q1) + charge2*unit_charge(temp-Q2)); // re-scale return (1.0/(E_temp|E_temp))*E_temp; } P potential(double x, double y) { // J rotates a vector by 1/4 turn; parallel to equipotentials return J(E(x,y)); } const double MAX(3); int main() { picture(P(-MAX,-MAX), P(MAX,MAX), "4x4in"); begin(); set_crop(); degrees(); // change angle mode // plot field lines blue(); for (int i=0; i < N; ++i) { // initial points trace a small circle about Q1 or Q2, ode_plot(E, Q1+polar(0.05, i*360.0/N), 10, 120); ode_plot(E, Q2-polar(0.05, i*360.0/N), 10, 120); // location of arrowhead P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3, 12)); } green(); for (int i=-10; i < 10; ++i) { ode_plot(potential, Q1+polar(0.25*pow(0.8, i), 0), 2*M_PI, 120); ode_plot(potential, Q2-polar(0.25*pow(0.8, i), 0), 2*M_PI, 120); } dot_size(6); circ(Q1); circ(Q2); magenta(); label(Q1, "\$+\$"); label(Q2, "\$+\$"); blue(); for (int i=0; i < N; ++i) { P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3.5, 12)); arrow(pt, pt+0.01*E(pt.x1(), pt.x2())); arrow(-pt, -pt+0.01*E(-pt.x1(), -pt.x2())); } end(); }