Charge b = aCharge(center=(0,0), q=1);
Charge c = nCharge(center=(-3u,0), q=-3);
Charge cs[] = {a,b,c};
-Distance dab = Distance(b.center, a.center, scale=u, L="$r_1$");
-Distance dbc = Distance(c.center, b.center, scale=u, L="$r_2$");
+Distance dab = Distance(b.center(), a.center(), scale=u, L="$r_1$");
+Distance dbc = Distance(c.center(), b.center(), scale=u, L="$r_2$");
Distance ds[] = {dab};
-Angle abc = Angle(a.center, b.center, c.center, radius=.5u, L="$\theta_T$");
-Angle bac = Angle(b.center, a.center, c.center, radius=-0.4u, L="$\phi_x$");
+Angle abc = Angle(
+ a.center(), b.center(), c.center(), radius=.5u, L="$\theta_T$");
+Angle bac = Angle(
+ b.center(), a.center(), c.center(), radius=-0.4u, L="$\phi_x$");
Angle as[] = {abc, bac};
//write(a.center.x);
Charge a = aCharge(center=(-2u, 2u), q=0);
a.draw();
-Vector v = EField(a.center, mag=u/2, dir=0,L="E"); v.draw();
-Vector v = BField(a.center, mag=u/2, dir=90,L="B"); v.draw();
-Vector v = Velocity(a.center, mag=u/2, dir=180,L="$v$"); v.draw();
+Vector v = EField(a.center(), mag=u/2, dir=0,L="E"); v.draw();
+Vector v = BField(a.center(), mag=u/2, dir=90,L="B"); v.draw();
+Vector v = Velocity(a.center(), mag=u/2, dir=180,L="$v$"); v.draw();
Vector Ic = Current(center=(-0.7u, 2.2u), phi=90, L="$I$"); Ic.draw();
draw(shift(Ic.center)*scale(16pt)*unitcircle, BFieldPen, ArcArrow);
// charged particle
struct Charge {
- pair center;
+ LabeledCircle lc;
real q;
- real radius;
- pen outline;
- pen fill;
- Label L;
- void operator init(pair center=(0,0), real q=1, real radius=2mm, pen outline=currentpen, pen fill=red, Label L="") {
- this.center = center;
+ void operator init(pair center=(0,0), real q=1, real radius=2mm,
+ pen outline=currentpen, pen fill=red, Label label="") {
+ this.lc.operator init(center=center, radius=radius, outline=outline,
+ fill=fill, label=label);
this.q = q;
- this.radius = radius;
- this.outline = outline;
- this.fill = fill;
- this.L = L;
- }
-
- void draw(picture pic=currentpicture) {
- picture picF;
- picture picL;
- label(picL, L);
- pair pLabelSize = 1.2 * (max(picL)-min(picL));
- path c = scale(radius)*unitcircle;
- filldraw(picF, c, fill, outline);
- label(pic = picF,
- L = L,
- position = (0,-(radius+pLabelSize.y/2)));
- add(pic, picF, center);
}
+
+ pair center() { return this.lc.center; }
+ void set_center(pair center) { this.lc.center = center; }
+ void draw(picture pic=currentpicture) = this.lc.draw;
}
// positive charge
-Charge pCharge(pair center=(0,0), real q=1, real radius=2mm, pen outline=currentpen, Label L="")
+Charge pCharge(pair center=(0,0), real q=1, real radius=2mm,
+ pen outline=currentpen, Label label="")
{
- Charge c = Charge(center=center, q=q, radius=radius, outline=outline, L=L, fill=red);
- return c;
+ return Charge(center=center, q=q, radius=radius, outline=outline, fill=red,
+ label=label);
}
// negative charge
-Charge nCharge(pair center=(0,0), real q=-1, real radius=2mm, pen outline=currentpen, Label L="")
+Charge nCharge(pair center=(0,0), real q=-1, real radius=2mm,
+ pen outline=currentpen, Label label="")
{
- Charge c = Charge(center=center, q=q, radius=radius, outline=outline, L=L, fill=blue);
- return c;
+ return Charge(center=center, q=q, radius=radius, outline=outline, fill=blue,
+ label=label);
}
// neutral charge
-Charge neutralCharge(pair center=(0,0), real radius=2mm, pen outline=currentpen, Label L="")
+Charge neutralCharge(pair center=(0,0), real radius=2mm,
+ pen outline=currentpen, Label label="")
{
- Charge c = Charge(center=center, q=0, radius=radius, outline=outline, L=L, fill=grey);
- return c;
+ return Charge(center=center, q=0, radius=radius, outline=outline, fill=grey,
+ label=label);
}
// auto-signed charge
-Charge aCharge(pair center=(0,0), real q=1, real radius=2mm, pen outline=currentpen, Label L="")
+Charge aCharge(pair center=(0,0), real q=1, real radius=2mm,
+ pen outline=currentpen, Label label="")
{
Charge c;
if (q > 0) {
- c = pCharge(center, q, radius, outline, L);
+ c = pCharge(center, q, radius, outline, label);
} else if (q < 0) {
- c = nCharge(center, q, radius, outline, L);
+ c = nCharge(center, q, radius, outline, label);
} else {
- c = neutralCharge(center, radius, outline, L);
+ c = neutralCharge(center, radius, outline, label);
}
return c;
}
// Force of a on b
Vector CoulombForce(Charge a, Charge b, Label L="", real scale=1mm, real unit=1mm)
{
- pair r = b.center - a.center;
+ pair r = b.center() - a.center();
real mag, dir;
mag = ((a.q*b.q)*(scale/length(r))^2)*unit;
dir = degrees(r);
- Vector v = Force(center=b.center, mag=mag, dir=dir, L=L);
+ Vector v = Force(center=b.center(), mag=mag, dir=dir, L=L);
return v;
}
real u = 1cm;
+LabeledCircle lc = LabeledCircle(center=(-2u, 1u));
+lc.draw();
+lc.label = "a";
+lc.center = (-2u, 0.5u);
+lc.draw();
+lc.draw_label(label=Label("e", align=E));
+lc.center = (-2u, 0);
+lc.label.align = W;
+lc.draw();
+lc.draw_label(label="b");
+lc.draw_label(label=Label("c", align=E));
+lc.draw_label(label=rotate(90)*Label("e------I", align=S));
+lc.draw_label(label=rotate(45)*Label("e------I", align=S));
+lc.center = (-2u, -2u);
+lc.radius = u/2;
+lc.label.align = E;
+lc.draw();
+lc.center = (-2u, -3u);
+lc.label.align = E;
+lc.draw();
+
Mass a = Mass(center=(0,0));
Mass b = Mass(center=(2u,1u));
Mass c = Mass(center=(1u,-2u));
Mass ms[] = {a,b, c};
-Distance dab = Distance(a.center, b.center, scale=u, L="$r_{ab}$");
-Distance dac = Distance(a.center, c.center, scale=u, L="$r_{ac}$");
+Distance dab = Distance(a.center(), b.center(), scale=u, L="$r_{ab}$");
+Distance dac = Distance(a.center(), c.center(), scale=u, L="$r_{ac}$");
Distance ds[] = {dab, dac};
Angle bac1 = Angle(
- b.center, a.center, c.center, radius=.7u, fill=red, L="$\theta_T'$");
-Angle bac2 = Angle(b.center, a.center, c.center, radius=-.5u, L="$\theta_T$");
+ b.center(), a.center(), c.center(), radius=.7u, fill=red, L="$\theta_T'$");
+Angle bac2 = Angle(
+ b.center(), a.center(), c.center(), radius=-.5u, L="$\theta_T$");
Angle as[] = {bac1, bac2};
Vector vs[];
Pendulum p = makePendulum(pivot=(3.5u,-3u), mass=b, length=4u, angleDeg=-20,
angleL="$\rho$", stringL="r");
-real len = abs(p.pivot.x-b.center.x);
-Spring s = Spring(pFrom=b.center-(2u,0), pTo=b.center, L="$k_1$"); s.draw();
-s = Spring(pFrom=b.center, pTo=(p.pivot.x, b.center.y), L="$k_2$"); s.draw();
+real len = abs(p.pivot.x-b.center().x);
+Spring s = Spring(pFrom=b.center()-(2u,0), pTo=b.center(), L="$k_1$");
+s.draw();
+s = Spring(pFrom=b.center(), pTo=(p.pivot.x, b.center().y), L="$k_2$");
+s.draw();
p.draw(drawVertical=true);
import geometry;
-// ---------------------- Mass -------------------------
+// ----------------- Labeled circle --------------------
-struct Mass {
+struct LabeledCircle {
pair center;
- real m;
real radius;
pen outline;
pen fill;
- Label L;
-
- void operator init(pair center=(0,0), real m=1, real radius=2mm, pen outline=currentpen, pen fill=grey, Label L="") {
+ Label label;
+
+ void operator init(pair center=(0,0), real radius=2mm,
+ pen outline=currentpen, pen fill=grey, Label label="") {
this.center = center;
- this.m = m;
this.radius = radius;
this.outline = outline;
this.fill = fill;
- this.L = L;
+ this.label = label;
}
-
+
+ void draw_label(picture pic=currentpicture, Label label=null) {
+ picture picL;
+ align a;
+ if (label == null) {
+ label = this.label;
+ }
+ a = label.align;
+ if (label.align != NoAlign && label.align != Align) {
+ real m = labelmargin(label.p);
+ real scale = (m + this.radius)/m;
+ if (label.align.is3D) {
+ label.align.dir3 *= scale;
+ } else {
+ label.align.dir *= scale;
+ }
+ }
+ label(pic=pic, L=label, position=this.center);
+ label.align = a;
+ }
+
void draw(picture pic=currentpicture) {
- picture picF;
- path c = scale(radius)*unitcircle;
- filldraw(picF, c, fill, outline);
- label(pic=picF, L=L, position=(0,0));
- add(pic, picF, center);
+ path p = shift(this.center)*scale(this.radius)*unitcircle;
+ filldraw(pic, p, this.fill, this.outline);
+ this.draw_label(pic=pic);
}
}
+// ---------------------- Mass -------------------------
+
+struct Mass {
+ LabeledCircle lc;
+ real m;
+
+ void operator init(pair center=(0,0), real m=1, real radius=2mm,
+ pen outline=currentpen, pen fill=grey, Label label="") {
+ this.lc.operator init(center=center, radius=radius, outline=outline,
+ fill=fill, label=label);
+ this.m = m;
+ }
+
+ pair center() { return this.lc.center; }
+ void set_center(pair center) { this.lc.center = center; }
+ void draw(picture pic=currentpicture) = this.lc.draw;
+}
+
struct Block {
pair center;
real m;
void operator init(pair pivot=(0,0), Mass mass=Mass()) {
this.pivot = pivot;
this.mass = mass;
- this.angle = Angle(mass.center, pivot, pivot-(0,1));
- this.str = Wire(pivot, mass.center);
+ this.angle = Angle(mass.center(), pivot, pivot-(0,1));
+ this.str = Wire(pivot, mass.center());
}
void draw(picture pic=currentpicture, bool drawVertical=false) {
str.draw(pic=pic, rotateLabel=false);
if (drawVertical == true) {
- pair final = pivot + realmult((0,0.5),(mass.center-pivot));
+ pair final = pivot + realmult((0,0.5),(mass.center()-pivot));
draw(pic=pic, pivot--final, p=currentpen+dashed);
}
draw(pic=pic, pivot);
// The angle argument is deflection from straight down (i.e. 0 degrees = plumb)
Pendulum makePendulum(pair pivot=(0,0), Mass mass=Mass(), real length=15mm, real angleDeg=0, Label angleL="", Label stringL="") {
- mass.center = pivot + length*dir(angleDeg-90);
+ mass.set_center(pivot + length*dir(angleDeg-90));
Pendulum p = Pendulum(pivot=pivot, mass=mass);
p.angle.L = angleL;
p.str.L = stringL;