*/
import geometry;
+import three;
// ----------------- Labeled circle --------------------
+void label_path(picture pic=currentpicture, Label L, path g, real margin=0,
+ pair rdir=0) {
+ align a = L.align;
+ embed e = L.embed;
+ real m = labelmargin(L.p);
+ real scale = (m + margin)/m;
+ if (L.align.is3D) {
+ L.align.dir3 *= scale;
+ } else {
+ L.align.dir *= scale;
+ }
+ if (L.embed == Rotate) {
+ L.embed = Rotate(rdir);
+ }
+ label(pic=pic, L=L, g=g);
+ L.align = a;
+ L.embed = e;
+}
+
+void label_path(picture pic=currentpicture, Label L, path3 g, real margin=0,
+ pair rdir=0) {
+ align a = L.align;
+ embed e = L.embed;
+ real m = labelmargin(L.p);
+ real scale = (m + margin)/m;
+ if (L.align.is3D) {
+ L.align.dir3 *= scale;
+ } else {
+ L.align.dir *= scale;
+ }
+ if (L.embed == Rotate) {
+ L.embed = Rotate(rdir);
+ }
+ label(pic=pic, L=L, g=g);
+ L.align = a;
+ L.embed = e;
+}
+
struct LabeledCircle {
pair center;
real radius;
}
void draw(picture pic=currentpicture) {
- picture picF;
pair p = this.dTip();
path P;
real phi_e = this.phi % 360; // effective phi
if (Tan(phi_e) == 0 || abs(1.0/Tan(phi_e)) > this.out_of_plane_tolerance) {
// draw arrow in the plane of the drawing
// TODO: thickening for phi?
- P = (0,0)--p;
- draw(picF, P, outline, Arrow);
+ P = shift(this.center)*((0,0)--p);
+ draw(pic, P, this.outline, Arrow);
} else if (phi_e > 0 && phi_e < 180) {
// draw a circled dot for out-of-the-page
- P = scale(this.out_of_plane_radius)*unitcircle;
- draw(picF, P, outline);
- dot(picF, (0,0), outline);
+ P = shift(this.center)*scale(this.out_of_plane_radius)*unitcircle;
+ draw(pic, P, outline);
+ dot(pic, this.center, this.outline);
} else {
// draw a circled cross for into-the-page
real a = 0.8*sqrt(2.0)/2.0;
- P = scale(this.out_of_plane_radius)*unitcircle;
- draw(picF, P, outline);
- draw(picF, scale(this.out_of_plane_radius)*((-a,-a)--(a,a)), outline);
- draw(picF, scale(this.out_of_plane_radius)*((-a,a)--(a,-a)), outline);
+ P = shift(this.center)*scale(this.out_of_plane_radius)*unitcircle;
+ draw(pic, P, this.outline);
+ draw(pic, shift(this.center)*scale(this.out_of_plane_radius
+ )*((-a,-a)--(a,a)), this.outline);
+ draw(pic, shift(this.center)*scale(this.out_of_plane_radius
+ )*((-a,a)--(a,-a)), this.outline);
}
- label(pic=picF, L=this.label, g=P);
- add(pic, picF, center);
+ label_path(pic=pic, L=this.label, g=P);
}
}
pair o = this.offset*unit(rotate(-90)*(this.pTo - this.pFrom));
path p = (this.pFrom+o) -- (this.pTo+o);
draw(pic, p, outline, Arrows);
- embed e = this.label.embed;
- if (this.label.embed == Rotate) {
- this.label.embed = Rotate(this.pTo - this.pFrom);
- }
- label(pic=pic, L=this.label, g=p);
- this.label.embed = e;
+ label_path(pic=pic, L=this.label, g=p, rdir=this.pTo - this.pFrom);
}
}
}
void draw(picture pic=currentpicture) {
- picture picF;
bool direction;
real ccw_angle = degrees(C-A)-degrees(B-A);
direction = CW;
if (radius < 0)
direction = !direction;
- path p = arc((0,0), fabs(radius), degrees(B-A), degrees(C-A), direction);
+ path p = arc(this.A, fabs(radius), degrees(B-A), degrees(C-A), direction);
if (this.fill != invisible) {
- path pcycle = (0,0) -- p -- cycle;
- fill(picF, pcycle, this.fill);
+ path pcycle = this.A -- p -- cycle;
+ fill(pic, pcycle, this.fill);
}
- draw(picF, p, this.outline);
+ draw(pic, p, this.outline);
if (direction == CW) {
p = reverse(p);
}
- label(pic=picF, L=this.label, g=p);
- add(pic, picF, A);
+ label_path(pic=pic, L=this.label, g=p);
}
}
void draw(picture pic=currentpicture) {
path p = this.pFrom--this.pTo;
draw(pic, p, outline);
- embed e = this.label.embed;
- if (this.label.embed == Rotate) {
- this.label.embed = Rotate(this.pTo - this.pFrom);
- }
- label(pic=pic, L=this.label, g=p);
- this.label.embed = e;
+ label_path(pic=pic, L=this.label, g=p, rdir=this.pTo - this.pFrom);
}
}
pic=pic, g=p, pena=filla, a=this.pFrom,
penb=fillb, b=this.pFrom+pDepth);
draw(pic, p, outline);
- embed e = this.label.embed;
- if (this.label.embed == Rotate) {
- this.label.embed = Rotate(this.pTo - this.pFrom);
- }
- label(pic=pic, L=this.label,
- g=(this.pFrom+pDepth/2) -- (this.pTo+pDepth/2));
- this.label.embed = e;
+ label_path(pic=pic, L=this.label,
+ g=shift(pDepth/2)*(this.pFrom -- this.pTo), rdir=this.pTo - this.pFrom);
}
}
p = p--(loopStart+(deadLength,0));
p = shift(this.pFrom)*rotate(degrees(pDiff)) * p;
draw(pic, p, outline);
- align a = this.label.align;
- embed e = this.label.embed;
- real m = labelmargin(this.label.p);
- real scale = (m + this.width/2)/m;
- if (this.label.align.is3D) {
- this.label.align.dir3 *= scale;
- } else {
- this.label.align.dir *= scale;
- }
- if (this.label.embed == Rotate) {
- this.label.embed = Rotate(this.pTo - this.pFrom);
- }
- label(pic=pic, L=this.label, g=this.pFrom -- this.pTo);
- this.label.align = a;
- this.label.embed = e;
+ label_path(pic=pic, L=this.label, g=this.pFrom--this.pTo,
+ margin=this.width/2, rdir=this.pTo - this.pFrom);
}
}
return p;
}
+struct Ring {
+ triple center;
+ triple normal;
+ real radius;
+ real width;
+ real axis_pre;
+ real axis_post;
+ pen outline;
+ pen fill;
+ pen axis;
+ Label label;
+ Label axis_label;
+
+ void operator init(triple center=(0,0,0), triple normal=(0,0,1),
+ real radius=5mm, real width=1mm, real axis_pre=0,
+ real axis_post=0, pen outline=currentpen,
+ pen fill=invisible, pen axis=invisible, Label L="",
+ Label axis_label="") {
+ this.center = center;
+ this.normal = normal;
+ this.radius = radius;
+ this.width = width;
+ this.axis_pre = axis_pre;
+ this.axis_post = axis_post;
+ this.outline = outline;
+ this.fill = fill;
+ this.axis = axis;
+ this.label = L;
+ this.axis_label = axis_label;
+ }
+
+ void draw(picture pic=currentpicture) {
+ path3 a = shift(this.center)*(
+ (-this.axis_pre*this.normal)--(this.axis_post*this.normal));
+ draw(pic, a, this.axis, Arrow3);
+ path3 c = circle(c=this.center, r=this.radius, normal=this.normal);
+ //tube t = tube(c, width=this.width); // slow and ugly!
+ //draw(t.s, this.fill);
+ draw(pic, c, this.outline);
+ label_path(pic=pic, L=this.label, g=c);
+ label_path(pic=pic, L=this.axis_label, g=a);
+ }
+}
-// TODO: ring, plate, cylinder, table
+// TODO: plate, cylinder, table