1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* -*-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();
}
|