summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/base/three_surface.asy
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2016-03-14 22:52:10 +0000
committerKarl Berry <karl@freefriends.org>2016-03-14 22:52:10 +0000
commit355bf72b81c6931539dd365430e78ebc10bcd0a2 (patch)
treeff9e855fb9eeb6cbc286d58e6cfe07bdb9cdf4ba /Build/source/utils/asymptote/base/three_surface.asy
parent1cdee1080e0ad8f88624629e00039d9fe89c1b54 (diff)
asy 2.37 sources
git-svn-id: svn://tug.org/texlive/trunk@40025 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.asy144
1 files changed, 98 insertions, 46 deletions
diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy
index 175ef562d80..c6d439e9fb0 100644
--- a/Build/source/utils/asymptote/base/three_surface.asy
+++ b/Build/source/utils/asymptote/base/three_surface.asy
@@ -68,7 +68,9 @@ struct patch {
}
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 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) {
return bezierPP(P[0][j],P[1][j],P[2][j],P[3][j],u);
}
@@ -82,7 +84,9 @@ struct patch {
}
triple Bv(int i, real v) {return bezier(P[i][0],P[i][1],P[i][2],P[i][3],v);}
- triple BvP(int i, real v) {return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);}
+ triple BvP(int i, real v) {
+ return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);
+ }
triple BvPP(int i, real v) {
return bezierPP(P[i][0],P[i][1],P[i][2],P[i][3],v);
}
@@ -99,13 +103,6 @@ struct patch {
return bezier(Bu(0,u),Bu(1,u),Bu(2,u),Bu(3,u),v);
}
- triple pointtriangular(real u, real v) {
- real w=1-u-v;
- return w^2*(w*P[0][0]+3*(u*P[1][0]+v*P[1][1]))+
- u^2*(u*P[3][0]+3*(w*P[2][0]+v*P[3][1]))+
- 6*u*v*w*P[2][1]+v^2*(v*P[3][3]+3*(w*P[2][2]+u*P[3][2]));
- }
-
// compute normal vectors for degenerate cases
private triple normal0(real u, real v, real epsilon) {
triple n=0.5*(cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),
@@ -167,46 +164,92 @@ struct patch {
return abs(n) > epsilon ? n : normal0(0,1,epsilon);
}
- triple normal00triangular() {
- triple n=9*cross(P[1][0]-P[0][0],P[1][1]-P[0][0]);
- real epsilon=fuzz*change2(P);
- return abs(n) > epsilon ? n : normal0(0,0,epsilon);
+ triple pointtriangular(real u, real v) {
+ real w=1-u-v;
+ return w^2*(w*P[0][0]+3*(u*P[1][0]+v*P[1][1]))+
+ u^2*(3*(w*P[2][0]+v*P[3][1])+u*P[3][0])+
+ 6*u*v*w*P[2][1]+v^2*(3*(w*P[2][2]+u*P[3][2])+v*P[3][3]);
}
- triple normal10triangular() {
- triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[2][0]);
- real epsilon=fuzz*change2(P);
- return abs(n) > epsilon ? n : normal0(1,0,epsilon);
+ triple bu(real u, real v) {
+ // Compute one-third of the directional derivative of a Bezier triangle
+ // in the u direction at (u,v).
+ real w=1-u-v;
+ return -w^2*P[0][0]+w*(w-2*u)*P[1][0]-2*w*v*P[1][1]+u*(2*w-u)*P[2][0]+
+ 2*v*(w-u)*P[2][1]-v^2*P[2][2]+u^2*P[3][0]+2*u*v*P[3][1]+v^2*P[3][2];
}
- triple normal01triangular() {
- triple n=9*cross(P[3][2]-P[2][2],P[3][3]-P[2][2]);
- real epsilon=fuzz*change2(P);
- return abs(n) > epsilon ? n : normal0(0,1,epsilon);
+ triple buu(real u, real v) {
+ // Compute one-sixth of the second directional derivative of a Bezier
+ // triangle in the u direction at (u,v).
+ real w=1-u-v;
+ return w*P[0][0]+(u-2*w)*P[1][0]+v*P[1][1]+(w-2*u)*P[2][0]-2*v*P[2][1]+
+ u*P[3][0]+v*P[3][1];
}
- // Compute one-third of the directional derivative of a Bezier triangle in the u
- // direction at point (u,v).
- private triple bu(real u, real v) {
+ triple buuu() {
+ // Compute one-sixth of the third directional derivative of a Bezier
+ // triangle in the u direction at (u,v).
+ return -P[0][0]+3*P[1][0]-3*P[2][0]+P[3][0];
+ }
+
+ triple bv(real u, real v) {
+ // Compute one-third of the directional derivative of a Bezier triangle
+ // in the v direction at (u,v).
real w=1-u-v;
- return u*(w*2-u)*P[2][0]+2*v*(w-u)*P[2][1]+w*(w-2*u)*P[1][0]+
- u*(u*P[3][0]+2*v*P[3][1])+v*v*P[3][2]-w*(2*v*P[1][1]+w*P[0][0])-
- v*v*P[2][2];
+ return -w^2*P[0][0]-2*u*w*P[1][0]+w*(w-2*v)*P[1][1]-u^2*P[2][0]+
+ 2*u*(w-v)*P[2][1]+v*(2*w-v)*P[2][2]+u*u*P[3][1]+2*u*v*P[3][2]+
+ v^2*P[3][3];
}
- // Compute one-third of the directional derivative of a Bezier triangle in the v
- // direction at point (u,v).
- private triple bv(real u, real v) {
+ triple bvv(real u, real v) {
+ // Compute one-sixth of the second directional derivative of a Bezier
+ // triangle in the v direction at (u,v).
real w=1-u-v;
- return u*2*(w-v)*P[2][1]+v*(2*w-v)*P[2][2]+w*(w-2*v)*P[1][1]+
- u*(u*P[3][1]+2*v*P[3][2])+v*v*P[3][3]-w*(2*u*P[1][0]+w*P[0][0])-
- u*u*P[2][0];
+ return w*P[0][0]+u*P[1][0]+(v-2*w)*P[1][1]-2*u*P[2][1]+(w-2*v)*P[2][2]+
+ u*P[3][2]+v*P[3][3];
+ }
+
+ triple bvvv() {
+ // Compute one-sixth of the third directional derivative of a Bezier
+ // triangle in the v direction at (u,v).
+ return -P[0][0]+3*P[1][1]-3*P[2][2]+P[3][3];
+ }
+
+ // compute normal vectors for a degenerate Bezier triangle
+ private triple normaltriangular0(real u, real v, real epsilon) {
+ triple n=9*(cross(buu(u,v),bv(u,v))+
+ cross(bu(u,v),bvv(u,v)));
+ return abs(n) > epsilon ? n :
+ 9*cross(buu(u,v),bvv(u,v))+
+ 3*(cross(buuu(),bv(u,v))+cross(bu(u,v),bvvv())+
+ cross(buuu(),bvv(u,v))+cross(buu(u,v),bvvv()))+
+ cross(buuu(),bvvv());
}
// Compute the normal of a Bezier triangle at (u,v)
triple normaltriangular(real u, real v) {
- // TODO: handle degeneracy
- return 9*cross(bu(u,v),bv(u,v));
+ triple n=9*cross(bu(u,v),bv(u,v));
+ real epsilon=fuzz*change2(P);
+ return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
+ }
+
+ triple normal00triangular() {
+ triple n=9*cross(P[1][0]-P[0][0],P[1][1]-P[0][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(0,0,epsilon);
+ }
+
+ triple normal10triangular() {
+ triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[2][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(1,0,epsilon);
+ }
+
+ triple normal01triangular() {
+ triple n=9*cross(P[3][2]-P[2][2],P[3][3]-P[2][2]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(0,1,epsilon);
}
pen[] colors(material m, light light=currentlight) {
@@ -255,6 +298,8 @@ struct patch {
normal10=normal10triangular;
normal01=normal01triangular;
colors=colorstriangular;
+ uequals=new path3(real u) {return nullpath3;};
+ vequals=new path3(real u) {return nullpath3;};
}
}
@@ -448,7 +493,7 @@ patch reverse(patch s)
assert(!s.triangular);
patch S;
S.P=transpose(s.P);
- if(s.colors.length > 0)
+ if(s.colors.length > 0)
S.colors=new pen[] {s.colors[0],s.colors[3],s.colors[2],s.colors[1]};
S.straight=s.straight;
S.planar=s.planar;
@@ -817,15 +862,15 @@ struct surface {
return ucyclic() ? g&cycle : g;
}
- // A constructor for a possibly nonconvex simple cyclic path in a given plane.
+ // A constructor for a possibly nonconvex simple cyclic path in a given
+ // plane.
void operator init(path p, triple plane(pair)=XYplane) {
- bool straight=piecewisestraight(p);
for(path g : regularize(p)) {
if(length(g) == 3) {
path3 G=path3(g,plane);
- s.push(patch(G,coons3(G)));
+ s.push(patch(G,coons3(G),planar=true));
} else
- s.push(patch(coons(g),plane,straight));
+ s.push(patch(coons(g),plane,piecewisestraight(g)));
}
}
@@ -1490,9 +1535,14 @@ void tensorshade(transform t=identity(), frame f, patch s,
material m, light light=currentlight, projection P)
{
- if(s.triangular) s=tensor(s);
+ pen[] p;
+ if(s.triangular) {
+ p=s.colorstriangular(m,light);
+ p.push(p[0]);
+ s=tensor(s);
+ } else p=s.colors(m,light);
tensorshade(f,box(t*s.min(P),t*s.max(P)),m.diffuse(),
- s.colors(m,light),t*project(s.external(),P,1),t*project(s.internal(),P));
+ p,t*project(s.external(),P,1),t*project(s.internal(),P));
}
restricted pen[] nullpens={nullpen};
@@ -1536,18 +1586,19 @@ void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
for(int p=depth.length-1; p >= 0; --p) {
real[] a=depth[p];
int k=round(a[1]);
+ patch S=s.s[k];
pen meshpen=meshpen[k];
- if(!invisible(meshpen)) {
+ if(!invisible(meshpen) && !S.triangular) {
if(group)
begingroup3(f,meshname(name),render);
meshpen=modifiers+meshpen;
real step=nu == 0 ? 0 : 1/nu;
for(int i=0; i <= nu; ++i)
- draw(f,s.s[k].uequals(i*step),meshpen,meshlight,partname(i,render),
+ draw(f,S.uequals(i*step),meshpen,meshlight,partname(i,render),
render);
step=nv == 0 ? 0 : 1/nv;
for(int j=0; j <= nv; ++j)
- draw(f,s.s[k].vequals(j*step),meshpen,meshlight,partname(j,render),
+ draw(f,S.vequals(j*step),meshpen,meshlight,partname(j,render),
render);
if(group)
endgroup3(f);
@@ -1629,8 +1680,9 @@ void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
pen modifiers;
if(is3D()) modifiers=thin()+squarecap;
for(int k=0; k < s.s.length; ++k) {
+ patch S=s.s[k];
pen meshpen=meshpen[k];
- if(!invisible(meshpen)) {
+ if(!invisible(meshpen) && !S.triangular) {
meshpen=modifiers+meshpen;
real step=nu == 0 ? 0 : 1/nu;
for(int i=0; i <= nu; ++i)