diff options
Diffstat (limited to 'Master/texmf-dist/asymptote/plain_prethree.asy')
-rw-r--r-- | Master/texmf-dist/asymptote/plain_prethree.asy | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/Master/texmf-dist/asymptote/plain_prethree.asy b/Master/texmf-dist/asymptote/plain_prethree.asy new file mode 100644 index 00000000000..595bac2fad4 --- /dev/null +++ b/Master/texmf-dist/asymptote/plain_prethree.asy @@ -0,0 +1,224 @@ +// Critical definitions for transform3 needed by projection and picture. + +typedef real[][] transform3; +restricted transform3 identity4=identity(4); + +// A uniform 3D scaling. +transform3 scale3(real s) +{ + transform3 t=identity(4); + t[0][0]=t[1][1]=t[2][2]=s; + return t; +} + +// Simultaneous 3D scalings in the x, y, and z directions. +transform3 scale(real x, real y, real z) +{ + transform3 t=identity(4); + t[0][0]=x; + t[1][1]=y; + t[2][2]=z; + return t; +} + +transform3 shiftless(transform3 t) +{ + transform3 T=copy(t); + T[0][3]=T[1][3]=T[2][3]=0; + return T; +} + +real camerafactor=2; // Factor used for camera adjustment. + +struct transformation { + transform3 modelview; // For orientation and positioning + transform3 projection; // For 3D to 2D projection + bool infinity; + void operator init(transform3 modelview) { + this.modelview=modelview; + this.projection=identity4; + infinity=true; + } + void operator init(transform3 modelview, transform3 projection) { + this.modelview=modelview; + this.projection=projection; + infinity=false; + } + transform3 compute() { + return infinity ? modelview : projection*modelview; + } + transformation copy() { + transformation T=new transformation; + T.modelview=copy(modelview); + T.projection=copy(projection); + T.infinity=infinity; + return T; + } +} + +struct projection { + transform3 t; // projection*modelview (cached) + bool infinity; + bool absolute=false; + triple camera; // Position of camera. + triple up; // A vector that should be projected to direction (0,1). + triple target; // Point where camera is looking at. + triple normal; // Normal vector from target to projection plane. + pair viewportshift; // Fractional viewport shift. + real zoom=1; // Zoom factor. + real angle; // Lens angle (for perspective projection). + bool showtarget=true; // Expand bounding volume to include target? + typedef transformation projector(triple camera, triple up, triple target); + projector projector; + bool autoadjust=true; // Adjust camera to lie outside bounding volume? + bool center=false; // Center target within bounding volume? + int ninterpolate; // Used for projecting nurbs to 2D Bezier curves. + bool bboxonly=true; // Typeset label bounding box only. + + transformation T; + + void calculate() { + T=projector(camera,up,target); + t=T.compute(); + infinity=T.infinity; + ninterpolate=infinity ? 1 : 16; + } + + triple vector() { + return camera-target; + } + + void operator init(triple camera, triple up=(0,0,1), triple target=(0,0,0), + triple normal=camera-target, + real zoom=1, real angle=0, pair viewportshift=0, + bool showtarget=true, bool autoadjust=true, + bool center=false, projector projector) { + this.camera=camera; + this.up=up; + this.target=target; + this.normal=normal; + this.zoom=zoom; + this.angle=angle; + this.viewportshift=viewportshift; + this.showtarget=showtarget; + this.autoadjust=autoadjust; + this.center=center; + this.projector=projector; + calculate(); + } + + projection copy() { + projection P=new projection; + P.t=t; + P.infinity=infinity; + P.absolute=absolute; + P.camera=camera; + P.up=up; + P.target=target; + P.normal=normal; + P.zoom=zoom; + P.angle=angle; + P.viewportshift=viewportshift; + P.showtarget=showtarget; + P.autoadjust=autoadjust; + P.center=center; + P.projector=projector; + P.ninterpolate=ninterpolate; + P.bboxonly=bboxonly; + P.T=T.copy(); + return P; + } + + // Return the maximum distance of box(m,M) from target. + real distance(triple m, triple M) { + triple[] c={m,(m.x,m.y,M.z),(m.x,M.y,m.z),(m.x,M.y,M.z), + (M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M}; + return max(abs(c-target)); + } + + + // This is redefined here to make projection as self-contained as possible. + static private real sqrtEpsilon = sqrt(realEpsilon); + + // Move the camera so that the box(m,M) rotated about target will always + // lie in front of the clipping plane. + bool adjust(triple m, triple M) { + triple v=camera-target; + real d=distance(m,M); + static real lambda=camerafactor*(1-sqrtEpsilon); + if(lambda*d >= abs(v)) { + camera=target+camerafactor*d*unit(v); + calculate(); + return true; + } + return false; + } +} + +projection currentprojection; + +struct light { + real[][] diffuse; + real[][] ambient; + real[][] specular; + pen background=nullpen; // Background color of the 3D canvas. + real specularfactor; + bool viewport; // Are the lights specified (and fixed) in the viewport frame? + triple[] position; // Only directional lights are currently implemented. + + transform3 T=identity(4); // Transform to apply to normal vectors. + + bool on() {return position.length > 0;} + + void operator init(pen[] diffuse, + pen[] ambient=array(diffuse.length,black), + pen[] specular=diffuse, pen background=nullpen, + real specularfactor=1, + bool viewport=false, triple[] position) { + int n=diffuse.length; + assert(ambient.length == n && specular.length == n && position.length == n); + + this.diffuse=new real[n][]; + this.ambient=new real[n][]; + this.specular=new real[n][]; + this.background=background; + this.position=new triple[n]; + for(int i=0; i < position.length; ++i) { + this.diffuse[i]=rgba(diffuse[i]); + this.ambient[i]=rgba(ambient[i]); + this.specular[i]=rgba(specular[i]); + this.position[i]=unit(position[i]); + } + this.specularfactor=specularfactor; + this.viewport=viewport; + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, real specularfactor=1, + bool viewport=false...triple[] position) { + int n=position.length; + operator init(array(n,diffuse),array(n,ambient),array(n,specular), + background,specularfactor,viewport,position); + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, bool viewport=false, + real x, real y, real z) { + operator init(diffuse,ambient,specular,background,viewport,(x,y,z)); + } + + void operator init(explicit light light) { + diffuse=copy(light.diffuse); + ambient=copy(light.ambient); + specular=copy(light.specular); + background=light.background; + specularfactor=light.specularfactor; + viewport=light.viewport; + position=copy(light.position); + } + + real[] background() {return rgba(background == nullpen ? white : background);} +} + +light currentlight; + |