Started versioning my asymptote libraries.
[course.git] / asymptote / ElectroMag.asy
1 import geometry;
2 import Mechanics;
3
4 // ---------------------- Charges -------------------------
5
6 struct Charge {
7   pair center;
8   real q;
9   real radius;
10   pen outline;
11   pen fill;
12   Label L;
13   
14   void operator init(pair center=(0,0), real q=1, real radius=2mm, pen outline=currentpen, pen fill=red, Label L="") {
15     this.center = center;
16     this.q = q;
17     this.radius = radius;
18     this.outline = outline;
19     this.fill = fill;
20     this.L = L;
21   }
22   
23   void draw(picture pic=currentpicture) {
24     frame picF;
25     path c = scale(radius)*unitcircle;
26     filldraw(picF, c, fill, outline);
27     // TODO: label
28     add(pic, picF, center);
29   }
30 }
31
32 Charge pCharge(pair center=(0,0), real q=1, real radius=2mm, pen outline=currentpen, Label L="")
33 {
34   Charge c = Charge(center=center, q=q, radius=radius, outline=outline, L=L, fill=red);
35   return c;
36 }
37
38 Charge nCharge(pair center=(0,0), real q=-1, real radius=2mm, pen outline=currentpen, Label L="")
39 {
40   Charge c = Charge(center=center, q=q, radius=radius, outline=outline, L=L, fill=blue);
41   return c;
42 }
43
44 // ---------------------- Vectors -------------------------
45
46 Vector EField(pair center=(0,0), real mag=5mm, real dir=0, Label L="")
47 {
48   Vector v = Vector(center=center, mag=mag, dir=dir, L=L, outline=rgb(1,0.5,0.2)); // orange
49   return v;
50 }
51
52 Vector BField(pair center=(0,0), real mag=5mm, real dir=0, Label L="")
53 {
54   Vector v = Vector(center=center, mag=mag, dir=dir, L=L, outline=rgb(0.1,1,0.2)); // green
55   return v;
56 }
57
58 Vector Velocity(pair center=(0,0), real mag=5mm, real dir=0, Label L="")
59 {
60   Vector v = Vector(center=center, mag=mag, dir=dir, L=L, outline=rgb(1,0.1,0.2)); // red
61   return v;
62 }
63
64 // ---------------------- Forces -------------------------
65
66 Vector Force(pair center=(0,0), real mag=5mm, real dir=0, Label L="")
67 {
68   Vector v = Vector(center=center, mag=mag, dir=dir, L=L, outline=rgb(0.1,0.2,1)); // blue
69   return v;
70 }
71
72 // Force of a on b
73 Vector CoulombForce(Charge a, Charge b, Label L="", real scale=1mm, real unit=1mm)
74 {
75   pair r = b.center - a.center;
76   real mag, dir;
77   mag = ((a.q*b.q)*(scale/length(r))^2)*unit;
78   dir = degrees(r);
79   Vector v = Force(center=b.center, mag=mag, dir=dir, L=L);
80   return v;
81 }
82
83 void CoulombForces(Charge c[], real scale=1mm, real unit=1mm)
84 {
85   Vector F;
86   string s;
87   for (int i=0; i<c.length; i+=1) {
88     for(int j=0; j<c.length; j+=1) {
89       if (i==j) continue;
90       s = "$F_{" + format("%d", i+1) + "," + format("%d", j+1) + "}$";
91       F = CoulombForce(c[i], c[j], L=s, scale=scale, unit=unit);
92       F.draw();
93     }
94   }
95 }
96
97 // ---------------------- Measures -------------------------
98
99 // Distance derived from CAD.MeasuredLine
100 struct Distance {
101   pair pFrom;
102   pair pTo;
103   real scale;
104   pen outline;
105   Label L;
106   
107   void operator init(pair pFrom=(0,0), pair pTo=(5mm,0), real scale=5mm, pen outline=currentpen, Label L="") {
108     this.pFrom = pFrom;
109     this.pTo = pTo;
110     this.outline = outline;
111     this.L = L;
112   }
113   
114   void draw(picture pic=currentpicture) {
115     picture picF;
116     picture picL;
117     label(picL, L);
118     pair pLabelSize = 1.2 * (max(picL)-min(picL));
119     pair pDiff = pTo - pFrom;
120     path p = (0,0)--pDiff;
121     draw(picF, p, outline, Arrows);
122     label(pic = picF,
123           L = rotate(degrees(pDiff)) * L,
124           position =
125           pDiff/2
126           + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
127     add(pic, picF, pFrom);
128   }
129 }
130
131 struct Angle {
132   pair B;
133   pair A;
134   pair C;
135   real radius; // radius < 0 for exterior angles.
136   pen outline;
137   Label L;
138
139   void operator init(pair B, pair A, pair C, real radius=5mm, pen outline=currentpen, Label L="") {
140     this.B = B;
141     this.A = A;
142     this.C = C;
143     this.radius = radius;
144     this.outline = outline;
145     this.L = L;
146   }
147   
148   void draw(picture pic=currentpicture) {
149     picture picF;
150     picture picL;
151     label(picL, L);
152     pair pLabelSize = 1.2 * (max(picL)-min(picL));
153     path p = arc(B-A, (0,0), C-A, radius);
154     real t = reltime(p, 0.5);
155     pair P = midpoint(p);
156     pair tang = dir(p, t);
157     
158     draw(picF, p, outline);    
159     label(pic = picF,
160           L = rotate(tang) * L,
161           position =
162           P + unit(P) * pLabelSize.y / 2);
163     add(pic, picF, A);
164   }
165 }
166
167 // TODO: ihat, ijhat
168
169 // ---------------------- Shapes -------------------------
170
171 // TODO: ring, plate, block, cylinder, spring, table
172
173