summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/base/three_surface.asy
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-28 23:56:03 +0000
committerKarl Berry <karl@freefriends.org>2009-05-28 23:56:03 +0000
commite767448d0591f5dbb0cd485e4b014becdcbd1ba4 (patch)
tree83bec5bd1ee117130f3e9dcee985dcd42f5145d9 /Build/source/utils/asymptote/base/three_surface.asy
parent20751a51df382b884807d8b9ef1ff7f7cc7739a5 (diff)
asymptote 1.74
git-svn-id: svn://tug.org/texlive/trunk@13514 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/base/three_surface.asy')
-rw-r--r--Build/source/utils/asymptote/base/three_surface.asy94
1 files changed, 58 insertions, 36 deletions
diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy
index 6e540c416ff..f1303d2e973 100644
--- a/Build/source/utils/asymptote/base/three_surface.asy
+++ b/Build/source/utils/asymptote/base/three_surface.asy
@@ -35,14 +35,6 @@ struct patch {
return new real[] {f(P[0][0]),f(P[0][3]),f(P[3][3]),f(P[3][0])};
}
- triple[] controlpoints() {
- return new triple[] {
- P[0][0],P[0][1],P[0][2],P[0][3],
- P[1][0],P[1][1],P[1][2],P[1][3],
- P[2][0],P[2][1],P[2][2],P[2][3],
- P[3][0],P[3][1],P[3][2],P[3][3]};
- }
-
triple Bu(int j, real u) {return bezier(P[0][j],P[1][j],P[2][j],P[3][j],u);}
triple BuP(int j, real u) {return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);}
triple BuPP(int j, real u) {
@@ -145,22 +137,6 @@ struct patch {
light.color(normal10(),nocolors ? m : colors[3])};
}
- triple bound(real m(real[], real), triple b) {
- real x=m(new real[] {P[0][0].x,P[0][1].x,P[0][2].x,P[0][3].x,
- P[1][0].x,P[1][1].x,P[1][2].x,P[1][3].x,
- P[2][0].x,P[2][1].x,P[2][2].x,P[2][3].x,
- P[3][0].x,P[3][1].x,P[3][2].x,P[3][3].x},b.x);
- real y=m(new real[] {P[0][0].y,P[0][1].y,P[0][2].y,P[0][3].y,
- P[1][0].y,P[1][1].y,P[1][2].y,P[1][3].y,
- P[2][0].y,P[2][1].y,P[2][2].y,P[2][3].y,
- P[3][0].y,P[3][1].y,P[3][2].y,P[3][3].y},b.y);
- real z=m(new real[] {P[0][0].z,P[0][1].z,P[0][2].z,P[0][3].z,
- P[1][0].z,P[1][1].z,P[1][2].z,P[1][3].z,
- P[2][0].z,P[2][1].z,P[2][2].z,P[2][3].z,
- P[3][0].z,P[3][1].z,P[3][2].z,P[3][3].z},b.z);
- return (x,y,z);
- }
-
triple min3,max3;
bool havemin3,havemax3;
@@ -172,13 +148,13 @@ struct patch {
triple min(triple bound=P[0][0]) {
if(havemin3) return minbound(min3,bound);
havemin3=true;
- return min3=bound(minbound,bound);
+ return min3=minbound(P,bound);
}
triple max(triple bound=P[0][0]) {
if(havemax3) return maxbound(max3,bound);
havemax3=true;
- return max3=bound(maxbound,bound);
+ return max3=maxbound(P,bound);
}
triple center() {
@@ -186,11 +162,11 @@ struct patch {
}
pair min(projection P, pair bound=project(this.P[0][0],P.t)) {
- return minbound(controlpoints(),P.t,bound);
+ return minbound(this.P,P.t,bound);
}
pair max(projection P, pair bound=project(this.P[0][0],P.t)) {
- return maxbound(controlpoints(),P.t,bound);
+ return maxbound(this.P,P.t,bound);
}
void operator init(triple[][] P, triple[] normals=new triple[],
@@ -901,6 +877,45 @@ patch subpatch(patch s, real ua, real va, real ub, real vb)
s.straight,s.planar);
}
+// return an array containing all intersection times of path p and patch s.
+real[][] intersections(path3 p, patch s, real fuzz=-1)
+{
+ return sort(intersections(p,s.P,fuzz));
+}
+
+// return an array containing all intersection times of path p and surface s.
+real[][] intersections(path3 p, surface s, real fuzz=-1)
+{
+ real[][] T;
+ if(length(p) < 0) return T;
+ for(int i=0; i < s.s.length; ++i)
+ for(real[] s: intersections(p,s.s[i].P,fuzz))
+ T.push(s);
+
+ sort(T);
+
+ static real fuzzFactor=10.0;
+ static real Fuzz=1000.0*realEpsilon;
+ real fuzz=max(fuzzFactor*fuzz,Fuzz)*abs(max(s)-min(s));
+
+ // Remove intrapatch duplicate points.
+ for(int i=0; i < T.length; ++i) {
+ for(int j=i+1; j < T.length;) {
+ if(abs(point(p,i)-point(p,j)) < fuzz)
+ T.delete(j);
+ else ++j;
+ }
+ }
+ return T;
+}
+
+// return an array containing all intersection points of path p and surface s.
+triple[] intersectionpoints(path3 p, surface s, real fuzz=-1)
+{
+ real[][] t=intersections(p,s,fuzz);
+ return sequence(new triple(int i) {return point(p,t[i][0]);},t.length);
+}
+
triple point(patch s, real u, real v)
{
return s.point(u,v);
@@ -1152,6 +1167,12 @@ void label(picture pic=currentpicture, Label L, triple position,
path[] g=texpath(L);
if(g.length == 0 || (g.length == 1 && size(g[0]) == 0)) return;
pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ // Handle relative projected 3D alignments.
+ Label L=L.copy();
+ if(!align.is3D && L.align.relative && L.align.dir3 != O &&
+ determinant(P.t) != 0)
+ L.align(L.align.dir*unit(project(L.align.dir3,P.t)));
+
triple v=t*position;
if(L.defaulttransform3)
L.T3=transform3(P);
@@ -1181,20 +1202,21 @@ void label(picture pic=currentpicture, Label L, triple position,
void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign,
pen p=currentpen)
{
- Label L=Label(L,align,p);
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
bool relative=L.position.relative;
real position=L.position.position.x;
- pair Align=L.align.dir;
- bool alignrelative=L.align.relative;
if(L.defaultposition) {relative=true; position=0.5;}
if(relative) position=reltime(g,position);
if(L.align.default) {
- alignrelative=true;
- Align=position <= 0 ? S : position >= length(g) ? N : E;
+ align a;
+ a.init(-I*(position <= sqrtEpsilon ? S :
+ position >= length(g)-sqrtEpsilon ? N : E),relative=true);
+ a.dir3=dir(g,position); // Pass 3D direction via unused field.
+ L.align(a);
}
- label(pic,L,point(g,position),
- alignrelative && determinant(currentprojection.t) != 0 ?
- -Align*project(dir(g,position),currentprojection.t)*I : L.align);
+ label(pic,L,point(g,position));
}
surface extrude(Label L, triple axis=Z)