13
Partial Differentiation To differentiate f ( x, y) with respect to x, treat y as a constant Examples 1. Let f ( x, y)= 2x 2 y 3 + sin x. Then f x = f x ( x, y)= 4xy 3 + cos x, f y = f y ( x, y)= 6x 2 y 2 2. Let f ( x, y, z)= x 2 + yz -1 . Then f x ( x, y, z)= 2x, f y ( x, y, z)= z -1 , f z ( x, y, z)= -yz -2 3. Let f ( x, y, z)= x 2 tan(yz 2 ). Then f x = 2x tan(yz 2 ), f y = x 2 z 2 sec 2 (yz 2 ), f z = 2x 2 yz sec 2 (yz 2 ) 15 Multiple Integrals 15.2 Iterated Integrals Interpretation: If R is a region in two-dimensions and f is an integrable function on R, then ZZ R f d A = f av · Area( R) where f av is the average value of the f over R. In particular RR R 1d A = Area( R) If E is the volume in three-dimensions above R and underneath the graph of z = f ( x, y), then ZZ R f d A = Volume( E) Otherwise said: Volume = Average height × Area of base Theorem (Fubini). Suppose R =[ a, b] × [c, d] a rectangle and f continuous. Then ZZ R f ( x, y) d A = Z b a Z d c f ( x, y) dy dx = Z d c Z b a f ( x, y) dx dy Order: evaluate inside integral first Z b a Z d c f ( x, y) dy dx Example If R =[1, 2] × [0, 1] and f ( x, y)= x 2 y, then ZZ R f ( x, y) d A = Z 1 0 Z 2 1 x 2 y dx dy = Z 1 0 1 3 x 3 y 2 x=1 dy = Z 1 0 7 3 y dy = 7 6 This is easy for separable functions Z b a Z d c g( x)h(y) dy dx = Z b a g( x) dx Z d c h(y) dy Recalling the previous example: f = gh where g( x)= x 2 and h(y)= y, whence ZZ R f ( x, y) d A = Z 1 0 Z 2 1 x 2 y dx dy = Z 2 1 x 2 dx Z 1 0 y dy = 7 3 · 1 2 = 7 6 1

15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

  • Upload
    others

  • View
    4

  • Download
    1

Embed Size (px)

Citation preview

Page 1: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Partial Differentiation To differentiate f (x y) with respect to x treat y as a constant

Examples

1 Let f (x y) = 2x2y3 + sin x Then

part fpartx

= fx(x y) = 4xy3 + cos xpart fparty

= fy(x y) = 6x2y2

2 Let f (x y z) = x2 + yzminus1 Then

fx(x y z) = 2x fy(x y z) = zminus1 fz(x y z) = minusyzminus2

3 Let f (x y z) = x2 tan(yz2) Then

fx = 2x tan(yz2) fy = x2z2 sec2(yz2) fz = 2x2yz sec2(yz2)

15 Multiple Integrals

152 Iterated Integrals

Interpretation If R is a region in two-dimensions and f is an integrable function on R thenintintR

f dA = fav middotArea(R)

where fav is the average value of the f over R In particularintint

R 1 dA = Area(R)

If E is the volume in three-dimensions above R and underneath the graph of z = f (x y) thenintintR

f dA = Volume(E)

Otherwise said Volume = Average heighttimesArea of base

Theorem (Fubini) Suppose R = [a b]times [c d] a rectangle and f continuous ThenintintR

f (x y)dA =int b

a

int d

cf (x y)dy dx =

int d

c

int b

af (x y)dx dy

Order evaluate inside integral firstint b

a

int d

cf (x y)dy dx

Example If R = [1 2]times [0 1] and f (x y) = x2y thenintintR

f (x y)dA =int 1

0

int 2

1x2y dx dy =

int 1

0

[13

x3y]2

x=1dy =

int 1

0

73

y dy =76

This is easy for separable functionsint b

a

int d

cg(x)h(y)dy dx =

int b

ag(x)dx

int d

ch(y)dy

Recalling the previous example f = gh where g(x) = x2 and h(y) = y whenceintintR

f (x y)dA =int 1

0

int 2

1x2y dx dy =

int 2

1x2 dx

int 1

0y dy =

73middot 1

2=

76

1

153 Double Integrals over General Regions

Type 1 a le x le b and g1(x) le y le g2(x)

Integrate with respect to y firstintintR

f (x y)dA =int b

a

int g2(x)

g1(x)f (x y)dy dx

y

x

y = g1(x)

y = g2(x)

a b

R

Example For R defined by 0 le x le 1 and 3x le y le 8minus 4x2 we have

intintR

x dA =int 1

0

int 8minus4x2

3xx dy dx =

int 1

0xy∣∣∣y=8minus4x2

y=3xdx =

int 1

08xminus 4x3 minus 3x2 dx

= 4x2 minus x4 minus x3∣∣∣10= 2

Type 2 h1(y) le x le h2(y) and c le y le d

Integrate with respect to x firstintintR

f (x y)dA =int d

c

int h2(x)

h1(x)f (x y)dy dx

y

x

x = h1(y)

x = h2(y)c

d

R

Example For R defined by 0 le y le 1 and y le x le ey we haveintintR

2x dA =int 1

0

int ey

y2x dx dy =

int 1

0x2∣∣∣x=ey

x=ydy =

int 1

0e2y minus y2 dy =

12

e2y minus 13

y3∣∣∣10

=12

e2 minus 13minus 1

2=

12

e2 minus 56

Both Type 1 + Type 2 Integrate either way

R can be describeda le x le b and g1(x) le y le g2(x) or

c le y le d and h1(y) le x le h2(y)

y

x

R

a b

c

d

2

Example Triangle T is a region of type 1

0 le x le 1 0 le y le 3minus 3x

and type 2

0 le y le 3 0 le x le 1minus y3

HenceintintT

x dA =int 1

0

int 3minus3x

0x dy dx =

int 1

03xminus 3x2 dx =

12

Or =int 3

0

int 1minus y3

0x dx dy =

int 3

0

12

(1minus y

3

)2dy =

12

0

1

2

3y

0 1x

T

Other regions Cut region two create several integrals of either type For example the followingregion may be sub-divided into two regions of type 1

RR1

R2

For any function f we haveintint

Rf dA =

intintR1

f dA +intint

R2

f dA

154 Double Integrals in Polar Co-ordinates

Polar co-ordinates

x = r cos θ

y = r sin θ

r =

radicx2 + y2

tan θ = yx

Infinitessimal Area Starting at (x y) increase polar co-ordinates by infinitessimal amounts dr and dθ Infinitessi-mal area is swept outa

dA =(

π(r + dr)2 minus πr2)dθ

2π= r dr dθ

since (dr)2 dr for infinitessimals

a dA is the area of a segment between two circles

y

r

dr

rdθdA

(x y)

3

Theorem Suppose that R is a polar rectangle defined by r1 le r le r2 and θ1 le θ le θ2 and that f is acontinuous function of R Thenintint

Rf (x y)dA =

int θ2

θ1

int r2

r1

f (r cos θ r sin θ) r dr dθ

Example Findintint

R4x + 3 dA for the annular region R described

by 1 le x2 + y2 le 4 with x y ge 0

In polar co-ordinates R is 1 le r le 2 and 0 le θ le π2 Hence

intintR

4x + 3 dA =int 2

1

int π2

04r2 cos θ + 3r dθ dr

=int 2

14r2 sin θ + 3θr

∣∣∣π2

θ=0dr

=int 2

14r2 +

2r dr =

283

+9π

40

1

2

0 1 2

R

Advanced The Theorem may be modified for regions of the plane where g(θ) le r le h(θ) for somefunctions of g h of r (the polar equivalent of Type 1)intint

Rf dA =

int θ2

θ1

int h(θ)

g(θ)f (r cos θ r sin θ) r dr dθ

A similarly approach can be taken for the analogue of a region of Type 2

Example The three-leaved rose has equation r = cos 3θFind its area

Choose R to be half of one leaf 0 le r le cos 3θ and 0 le θ le π6intint

RdA =

int π6

0

int cos 3θ

0r dr dθ =

int π6

0

12

r2∣∣∣cos 3θ

r=0dθ

=int π6

0

12

cos2 3θ dθ =14

int π6

0cos 6θ + 1 dθ

=14

[16

sin 6θ + θ

]π6

0=

π

24

By symmetry the total area of the rose is therefore 6 middot π

24=

π

4minus1

1

minus1 1

R

4

157 Triple Integrals

Interpretation If E is a region in two-dimensions and f is an integrable function on E thenintintintE

f dV = fav middotVolume(E)

where fav is the average value of the f over E In particularintintint

E 1 dV = Volume(E)

For example if T(x y z) is the temperature at a point (x y z) in a room E then the average temper-ature in the room is

Tav =1

Volume(E)

intintintE

f dVintintintE f dV can be interpreted as a hypervolume in four-dimensions but this is unhelpful to most of us

Theorem (Fubini) Suppose that E = [p q]times [r s]times [t u] is a cuboid and f is continuous on E ThenintintintE

f (x y z)dV =int q

p

int s

r

int u

tf (x y z)dz dy dx

More generally if E is the region defined by the inequalitiesa le x le bg1(x) le y le g2(x)h1(x y) le z le h2(x y)

then intintintE

f (x y z)dV =int b

a

int g2(x)

g1(x)

int h2(xy)

h1(xy)f (x y z)dz dy dx

In general there are six ways of ordering the variables x y z

Example Find the integralintintint

V f dV where

f (x y z) = x + 2yz

and V is defined by

0 le x y le 1xminus y le z le x + y

intintintV

f dV =int 1

0

int 1

0

int x+y

xminusyx + 2yz dz dy dx

=int 1

0

int 1

0xz + yz2

∣∣∣x+y

z=xminusydy dx

=int 1

0

int 1

0x(x + yminus (xminus y)) + y((x + y)2 minus (xminus y)2)dy dx

=int 1

0

int 1

02xy + 4xy2 dy dx =

76

5

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton0)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 2: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

153 Double Integrals over General Regions

Type 1 a le x le b and g1(x) le y le g2(x)

Integrate with respect to y firstintintR

f (x y)dA =int b

a

int g2(x)

g1(x)f (x y)dy dx

y

x

y = g1(x)

y = g2(x)

a b

R

Example For R defined by 0 le x le 1 and 3x le y le 8minus 4x2 we have

intintR

x dA =int 1

0

int 8minus4x2

3xx dy dx =

int 1

0xy∣∣∣y=8minus4x2

y=3xdx =

int 1

08xminus 4x3 minus 3x2 dx

= 4x2 minus x4 minus x3∣∣∣10= 2

Type 2 h1(y) le x le h2(y) and c le y le d

Integrate with respect to x firstintintR

f (x y)dA =int d

c

int h2(x)

h1(x)f (x y)dy dx

y

x

x = h1(y)

x = h2(y)c

d

R

Example For R defined by 0 le y le 1 and y le x le ey we haveintintR

2x dA =int 1

0

int ey

y2x dx dy =

int 1

0x2∣∣∣x=ey

x=ydy =

int 1

0e2y minus y2 dy =

12

e2y minus 13

y3∣∣∣10

=12

e2 minus 13minus 1

2=

12

e2 minus 56

Both Type 1 + Type 2 Integrate either way

R can be describeda le x le b and g1(x) le y le g2(x) or

c le y le d and h1(y) le x le h2(y)

y

x

R

a b

c

d

2

Example Triangle T is a region of type 1

0 le x le 1 0 le y le 3minus 3x

and type 2

0 le y le 3 0 le x le 1minus y3

HenceintintT

x dA =int 1

0

int 3minus3x

0x dy dx =

int 1

03xminus 3x2 dx =

12

Or =int 3

0

int 1minus y3

0x dx dy =

int 3

0

12

(1minus y

3

)2dy =

12

0

1

2

3y

0 1x

T

Other regions Cut region two create several integrals of either type For example the followingregion may be sub-divided into two regions of type 1

RR1

R2

For any function f we haveintint

Rf dA =

intintR1

f dA +intint

R2

f dA

154 Double Integrals in Polar Co-ordinates

Polar co-ordinates

x = r cos θ

y = r sin θ

r =

radicx2 + y2

tan θ = yx

Infinitessimal Area Starting at (x y) increase polar co-ordinates by infinitessimal amounts dr and dθ Infinitessi-mal area is swept outa

dA =(

π(r + dr)2 minus πr2)dθ

2π= r dr dθ

since (dr)2 dr for infinitessimals

a dA is the area of a segment between two circles

y

r

dr

rdθdA

(x y)

3

Theorem Suppose that R is a polar rectangle defined by r1 le r le r2 and θ1 le θ le θ2 and that f is acontinuous function of R Thenintint

Rf (x y)dA =

int θ2

θ1

int r2

r1

f (r cos θ r sin θ) r dr dθ

Example Findintint

R4x + 3 dA for the annular region R described

by 1 le x2 + y2 le 4 with x y ge 0

In polar co-ordinates R is 1 le r le 2 and 0 le θ le π2 Hence

intintR

4x + 3 dA =int 2

1

int π2

04r2 cos θ + 3r dθ dr

=int 2

14r2 sin θ + 3θr

∣∣∣π2

θ=0dr

=int 2

14r2 +

2r dr =

283

+9π

40

1

2

0 1 2

R

Advanced The Theorem may be modified for regions of the plane where g(θ) le r le h(θ) for somefunctions of g h of r (the polar equivalent of Type 1)intint

Rf dA =

int θ2

θ1

int h(θ)

g(θ)f (r cos θ r sin θ) r dr dθ

A similarly approach can be taken for the analogue of a region of Type 2

Example The three-leaved rose has equation r = cos 3θFind its area

Choose R to be half of one leaf 0 le r le cos 3θ and 0 le θ le π6intint

RdA =

int π6

0

int cos 3θ

0r dr dθ =

int π6

0

12

r2∣∣∣cos 3θ

r=0dθ

=int π6

0

12

cos2 3θ dθ =14

int π6

0cos 6θ + 1 dθ

=14

[16

sin 6θ + θ

]π6

0=

π

24

By symmetry the total area of the rose is therefore 6 middot π

24=

π

4minus1

1

minus1 1

R

4

157 Triple Integrals

Interpretation If E is a region in two-dimensions and f is an integrable function on E thenintintintE

f dV = fav middotVolume(E)

where fav is the average value of the f over E In particularintintint

E 1 dV = Volume(E)

For example if T(x y z) is the temperature at a point (x y z) in a room E then the average temper-ature in the room is

Tav =1

Volume(E)

intintintE

f dVintintintE f dV can be interpreted as a hypervolume in four-dimensions but this is unhelpful to most of us

Theorem (Fubini) Suppose that E = [p q]times [r s]times [t u] is a cuboid and f is continuous on E ThenintintintE

f (x y z)dV =int q

p

int s

r

int u

tf (x y z)dz dy dx

More generally if E is the region defined by the inequalitiesa le x le bg1(x) le y le g2(x)h1(x y) le z le h2(x y)

then intintintE

f (x y z)dV =int b

a

int g2(x)

g1(x)

int h2(xy)

h1(xy)f (x y z)dz dy dx

In general there are six ways of ordering the variables x y z

Example Find the integralintintint

V f dV where

f (x y z) = x + 2yz

and V is defined by

0 le x y le 1xminus y le z le x + y

intintintV

f dV =int 1

0

int 1

0

int x+y

xminusyx + 2yz dz dy dx

=int 1

0

int 1

0xz + yz2

∣∣∣x+y

z=xminusydy dx

=int 1

0

int 1

0x(x + yminus (xminus y)) + y((x + y)2 minus (xminus y)2)dy dx

=int 1

0

int 1

02xy + 4xy2 dy dx =

76

5

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton0)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 3: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Example Triangle T is a region of type 1

0 le x le 1 0 le y le 3minus 3x

and type 2

0 le y le 3 0 le x le 1minus y3

HenceintintT

x dA =int 1

0

int 3minus3x

0x dy dx =

int 1

03xminus 3x2 dx =

12

Or =int 3

0

int 1minus y3

0x dx dy =

int 3

0

12

(1minus y

3

)2dy =

12

0

1

2

3y

0 1x

T

Other regions Cut region two create several integrals of either type For example the followingregion may be sub-divided into two regions of type 1

RR1

R2

For any function f we haveintint

Rf dA =

intintR1

f dA +intint

R2

f dA

154 Double Integrals in Polar Co-ordinates

Polar co-ordinates

x = r cos θ

y = r sin θ

r =

radicx2 + y2

tan θ = yx

Infinitessimal Area Starting at (x y) increase polar co-ordinates by infinitessimal amounts dr and dθ Infinitessi-mal area is swept outa

dA =(

π(r + dr)2 minus πr2)dθ

2π= r dr dθ

since (dr)2 dr for infinitessimals

a dA is the area of a segment between two circles

y

r

dr

rdθdA

(x y)

3

Theorem Suppose that R is a polar rectangle defined by r1 le r le r2 and θ1 le θ le θ2 and that f is acontinuous function of R Thenintint

Rf (x y)dA =

int θ2

θ1

int r2

r1

f (r cos θ r sin θ) r dr dθ

Example Findintint

R4x + 3 dA for the annular region R described

by 1 le x2 + y2 le 4 with x y ge 0

In polar co-ordinates R is 1 le r le 2 and 0 le θ le π2 Hence

intintR

4x + 3 dA =int 2

1

int π2

04r2 cos θ + 3r dθ dr

=int 2

14r2 sin θ + 3θr

∣∣∣π2

θ=0dr

=int 2

14r2 +

2r dr =

283

+9π

40

1

2

0 1 2

R

Advanced The Theorem may be modified for regions of the plane where g(θ) le r le h(θ) for somefunctions of g h of r (the polar equivalent of Type 1)intint

Rf dA =

int θ2

θ1

int h(θ)

g(θ)f (r cos θ r sin θ) r dr dθ

A similarly approach can be taken for the analogue of a region of Type 2

Example The three-leaved rose has equation r = cos 3θFind its area

Choose R to be half of one leaf 0 le r le cos 3θ and 0 le θ le π6intint

RdA =

int π6

0

int cos 3θ

0r dr dθ =

int π6

0

12

r2∣∣∣cos 3θ

r=0dθ

=int π6

0

12

cos2 3θ dθ =14

int π6

0cos 6θ + 1 dθ

=14

[16

sin 6θ + θ

]π6

0=

π

24

By symmetry the total area of the rose is therefore 6 middot π

24=

π

4minus1

1

minus1 1

R

4

157 Triple Integrals

Interpretation If E is a region in two-dimensions and f is an integrable function on E thenintintintE

f dV = fav middotVolume(E)

where fav is the average value of the f over E In particularintintint

E 1 dV = Volume(E)

For example if T(x y z) is the temperature at a point (x y z) in a room E then the average temper-ature in the room is

Tav =1

Volume(E)

intintintE

f dVintintintE f dV can be interpreted as a hypervolume in four-dimensions but this is unhelpful to most of us

Theorem (Fubini) Suppose that E = [p q]times [r s]times [t u] is a cuboid and f is continuous on E ThenintintintE

f (x y z)dV =int q

p

int s

r

int u

tf (x y z)dz dy dx

More generally if E is the region defined by the inequalitiesa le x le bg1(x) le y le g2(x)h1(x y) le z le h2(x y)

then intintintE

f (x y z)dV =int b

a

int g2(x)

g1(x)

int h2(xy)

h1(xy)f (x y z)dz dy dx

In general there are six ways of ordering the variables x y z

Example Find the integralintintint

V f dV where

f (x y z) = x + 2yz

and V is defined by

0 le x y le 1xminus y le z le x + y

intintintV

f dV =int 1

0

int 1

0

int x+y

xminusyx + 2yz dz dy dx

=int 1

0

int 1

0xz + yz2

∣∣∣x+y

z=xminusydy dx

=int 1

0

int 1

0x(x + yminus (xminus y)) + y((x + y)2 minus (xminus y)2)dy dx

=int 1

0

int 1

02xy + 4xy2 dy dx =

76

5

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton0)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 4: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Theorem Suppose that R is a polar rectangle defined by r1 le r le r2 and θ1 le θ le θ2 and that f is acontinuous function of R Thenintint

Rf (x y)dA =

int θ2

θ1

int r2

r1

f (r cos θ r sin θ) r dr dθ

Example Findintint

R4x + 3 dA for the annular region R described

by 1 le x2 + y2 le 4 with x y ge 0

In polar co-ordinates R is 1 le r le 2 and 0 le θ le π2 Hence

intintR

4x + 3 dA =int 2

1

int π2

04r2 cos θ + 3r dθ dr

=int 2

14r2 sin θ + 3θr

∣∣∣π2

θ=0dr

=int 2

14r2 +

2r dr =

283

+9π

40

1

2

0 1 2

R

Advanced The Theorem may be modified for regions of the plane where g(θ) le r le h(θ) for somefunctions of g h of r (the polar equivalent of Type 1)intint

Rf dA =

int θ2

θ1

int h(θ)

g(θ)f (r cos θ r sin θ) r dr dθ

A similarly approach can be taken for the analogue of a region of Type 2

Example The three-leaved rose has equation r = cos 3θFind its area

Choose R to be half of one leaf 0 le r le cos 3θ and 0 le θ le π6intint

RdA =

int π6

0

int cos 3θ

0r dr dθ =

int π6

0

12

r2∣∣∣cos 3θ

r=0dθ

=int π6

0

12

cos2 3θ dθ =14

int π6

0cos 6θ + 1 dθ

=14

[16

sin 6θ + θ

]π6

0=

π

24

By symmetry the total area of the rose is therefore 6 middot π

24=

π

4minus1

1

minus1 1

R

4

157 Triple Integrals

Interpretation If E is a region in two-dimensions and f is an integrable function on E thenintintintE

f dV = fav middotVolume(E)

where fav is the average value of the f over E In particularintintint

E 1 dV = Volume(E)

For example if T(x y z) is the temperature at a point (x y z) in a room E then the average temper-ature in the room is

Tav =1

Volume(E)

intintintE

f dVintintintE f dV can be interpreted as a hypervolume in four-dimensions but this is unhelpful to most of us

Theorem (Fubini) Suppose that E = [p q]times [r s]times [t u] is a cuboid and f is continuous on E ThenintintintE

f (x y z)dV =int q

p

int s

r

int u

tf (x y z)dz dy dx

More generally if E is the region defined by the inequalitiesa le x le bg1(x) le y le g2(x)h1(x y) le z le h2(x y)

then intintintE

f (x y z)dV =int b

a

int g2(x)

g1(x)

int h2(xy)

h1(xy)f (x y z)dz dy dx

In general there are six ways of ordering the variables x y z

Example Find the integralintintint

V f dV where

f (x y z) = x + 2yz

and V is defined by

0 le x y le 1xminus y le z le x + y

intintintV

f dV =int 1

0

int 1

0

int x+y

xminusyx + 2yz dz dy dx

=int 1

0

int 1

0xz + yz2

∣∣∣x+y

z=xminusydy dx

=int 1

0

int 1

0x(x + yminus (xminus y)) + y((x + y)2 minus (xminus y)2)dy dx

=int 1

0

int 1

02xy + 4xy2 dy dx =

76

5

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton0)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 5: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

157 Triple Integrals

Interpretation If E is a region in two-dimensions and f is an integrable function on E thenintintintE

f dV = fav middotVolume(E)

where fav is the average value of the f over E In particularintintint

E 1 dV = Volume(E)

For example if T(x y z) is the temperature at a point (x y z) in a room E then the average temper-ature in the room is

Tav =1

Volume(E)

intintintE

f dVintintintE f dV can be interpreted as a hypervolume in four-dimensions but this is unhelpful to most of us

Theorem (Fubini) Suppose that E = [p q]times [r s]times [t u] is a cuboid and f is continuous on E ThenintintintE

f (x y z)dV =int q

p

int s

r

int u

tf (x y z)dz dy dx

More generally if E is the region defined by the inequalitiesa le x le bg1(x) le y le g2(x)h1(x y) le z le h2(x y)

then intintintE

f (x y z)dV =int b

a

int g2(x)

g1(x)

int h2(xy)

h1(xy)f (x y z)dz dy dx

In general there are six ways of ordering the variables x y z

Example Find the integralintintint

V f dV where

f (x y z) = x + 2yz

and V is defined by

0 le x y le 1xminus y le z le x + y

intintintV

f dV =int 1

0

int 1

0

int x+y

xminusyx + 2yz dz dy dx

=int 1

0

int 1

0xz + yz2

∣∣∣x+y

z=xminusydy dx

=int 1

0

int 1

0x(x + yminus (xminus y)) + y((x + y)2 minus (xminus y)2)dy dx

=int 1

0

int 1

02xy + 4xy2 dy dx =

76

5

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton0)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 6: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

158 Triple Integrals in Cylindrical Co-ordinates

Polar co-ordinates + z

dV = dA dz = r dr dθ dz

Useful when the domain of integration has rotationalsymmetry or when x2 + y2 is dominant in the integrandintintint

Ef dV =

intintintE

f (r cos θ r sin θ z)r dr dθ dz

Co-ordinate surfaces

Constant z horizontal planes

Constant r cylinders

Constant θ planes touching z-axis

Example Calculate the integral of the function

f (x y z) = x2 + y2 + 2z

under the paraboloidal cap z = 1minus x2 minus y2 and above thexy-plane

In cylindrical polars the cap has equation z = 1minus r2 andintersects the plane z = 0 in the circle r = 1 hence

intintintV

f dV =int 2π

0

int 1

0

int 1minusr2

0(2z + r2)r dz dr dθ

= 2πint 1

0rz2 + r3z

∣∣1minusr2

z=0 dr = 2πint 1

0r(1minus r2)2 + r3 minus r5 dr

= 2π

[minus1

6(1minus r2)3 +

14

r4 minus 16

r6]1

0=

π

2

6

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton1)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton2)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton3)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 7: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Example A cone has height h and circular base of radius RFind its volume using an integral

The cone is created by rotating the line joining (0 0 h) and(R 0 0) around the z-axis This line (in the xz-plane) hasequation

zh+

xR

= 1

Rotating this simply means replacing x with the radius thisthe cone has equation

zh+

rR

= 1 =rArr z = h(

1minus rR

)Its volume is thereforeintintint

VdV =

int 2π

0

int R

0

int h(1minus rR )

0r dz dr dθ = 2π

int R

0rh(

1minus rR

)dr

= 2πhint R

0rminus r2

Rdr = 2πh

(R2

2minus R3

3R

)=

13

πhR2

159 Triple Integrals in Spherical Co-ordinates

Three co-ordinatesρ the distance from the originφ the angle down from the positive z-axisθ the polar angle in the xy-plane

x = ρ sin φ cos θ

y = ρ sin φ sin θ

z = ρ cos φ

ρ ge 0 0 le φ le π 0 le θ lt 2π

ρ =radic

x2 + y2 + z2

tan θ =yx

cos φ =zρ

Compute infinitessimal volume by increasing eachco-ordinate by small amount volume swept out isapproximately cuboidal with volume

dV = dρ ρ sin φ dθ ρ dφ = ρ2 sin φ dρ dθ dφ

Warning In many places later on r is used instead of ρ make sure you know which co-ordinatesystem (cylindrical or spherical) you are using

7

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton4)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton5)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 8: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Example (x y z) = (1radic

3 3) has spherical polar co-ordinates

(ρ φ θ) =

(radic13 cosminus1 3radic

13

π

3

)

Co-ordinate surfaces

ρ constant sphere radius ρ

θ constant plane touching z-axis making angle θ withxz-plane

φ constant cone centered on z-axis angle φ from verti-cal

Example A sphere of radius R has volumeint π

0

int 2π

0

int R

0ρ2 sin φ dρ dθ dφ =

int π

0sin φ dφ

int 2π

0dθint R

0ρ2 dρ

= 2 middot 2π middot 13

R3 =43

πR3

Example A solid lies above the cone

z =radic

x2 + y2

and below the sphere

x2 + y2 + z2 = 1

Its volume isint π4

0

int 2π

0

int 1

0ρ2 sin φ dρ dθ dφ = (minus cos φ)

∣∣π40 middot 2π middot 1

3ρ3∣∣∣10

=

(1minus 1radic

2

)middot 2π middot 1

3=

(2minusradic

2)π3

8

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton6)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton7)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 9: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Example Find the integral of f (x y z) = yz over the vol-ume shown

1 le ρ le 2 0 le θ le π

0 le φ le π

2

intintintV

f dV =int 2

1

int π2

0

int π

0ρ sin φ sin θ ρ cos φ ρ2 sin φ dθ dφ dρ

=int 2

1ρ4 dρ middot

int π2

0cos φ sin2 φ dφ middot

int π

0sin θ dθ

=15(32minus 1) middot 1

3sin3 φ

∣∣π20 middot 2 =

6215

Example A plum is modeled by the equation

ρ = 1minus cos φ

If ρ is measured in inches find the volume of the plum

If you think back to 2D r = 1 minus cos θ is the equation of acardioid in polar co-ordinates The plum is just the surfaceformed by rotating a cardioid

Volume =int 2π

0

int π

0

int 1minuscos φ

0ρ2 sin φ dρ dφ dθ

= 2πint π

0

13(1minus cos φ)3 sin φ dφ

= 2π middot 112

(1minus cos φ)4∣∣∣π0= 2π middot 16

12=

3in3

For a sanity check this is precisely the volume of a sphere of radius 3radic

2 asymp 12599 in

9

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton8)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton9)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 10: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

1510 Change of Variables in Multiple Integrals

How to integrate in arbitrary co-ordinates

Definition Let (x y) = (x(u v) y(u v)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y)part(u v)

=partxpartumiddot party

partvminus partx

partvmiddot party

partu=

∣∣∣∣xu xvyu yv

∣∣∣∣ = z-component of

xuyu0

timesxv

yv0

Example Suppose x = uminus 2v and y = 3u + 4v Then

part(x y)part(u v)

= xuyv minus xvyu = 1 middot 4minus (minus2) middot 3 = 10

Theorem The Jacobian of the inverse transform (u v) = (u(x y) v(x y)) is

part(u v)part(x y)

=

(part(x y)part(u v)

)minus1

Example If x = uminus 2v and y = 3u + 4v then we may solve for u v to obtain

u =15(2x + y) and v =

110

(yminus 3x)

The inverse Jacobian is therefore

part(u v)part(x y)

= uxvy minus uyvx =25middot 1

10minus 1

5middot minus3

10=

110

What does this have to do with integration Let the par-allelogram R have corners (0 0) (1 3) (minus1 7) and (minus2 4)It is easy to see that its area is 1

2 middot 10 middot 2 = 10

Opposite edges of the parallelogram are parallel lines theequations of which are similarFor example y = minus2x and y = minus2x + 5 may be writteny + 2x = 0 and y + 2x = 5 on opposite edges the samefunction of x and y is equal to two different constants

y

x

(1 3)(minus2 4)

(minus1 7)

R

y

xy = 3x

y = 3x + 10

y = minus2x

y = minus2x + 5

(0 10)

R

If we define the functions u = 15 (2x + y) and v = 1

10 (yminus 3x) then the four edges of the parallelogrammay be described as u = 0 u = 1 v = 0 v = 1 With respect to the new co-ordinates (u v) theparallelogram becomes a square S with area 1

10

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 11: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

The factor relating the (u v)-area and the (x y)-area isprecisely the Jacobian

Area(xy) = 10Area(uv) =part(x y)part(u v)

Area(uv)

Written in terms of a double integral this readsintintR

dA =intint

Rdx dy =

intintS

part(x y)part(u v)

du dv

2

4

6

y

minus2minus1 0 1x

v = 0

v = 1

u = 0

u = 1

R

0

v

0u

S

1

1

The same idea applies to any change of co-ordinates Given a domain of integration R search forfunctions u(x y) v(x y) so that in terms of u v the domain becomes a simpler shape S one overwhich integration is simpler

Theorem Suppose S is a region in the (u v)-plane that ismapped 1ndash1 onto a region R in the (x y)-plane by a transforma-tion (x y) = T(u v) with continuous 1st partial derivatives If fis a continuous function on S thenintint

Rf (x y)dx dy =

intintS

f (T(u v))∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv

S(u v)

R(x y)

T

Warning Take the absolute value of the Jacobian This was not needed in our parallelogram examplesince the Jacobian was already positive

Example Find the moment of inertiaintint

R y2 dA of the par-allelogram R about the x-axis

First find the equations of the edges y = 4x y = 4x + 12and y = minus2x y = minus2x + 6 This suggests new co-ordinates

u = yminus 4x v = y + 2x

R becomes the rectangle S defined by 0 le u le 12 0 le v le 6

Compute the Jacobian

y

x

(1 4)(minus2 4)

(minus1 8)

R

00

u

S

12

6v

part(u v)part(x y)

=

∣∣∣∣ux uyvx vy

∣∣∣∣ = ∣∣∣∣minus4 12 1

∣∣∣∣ = minus6

Finally solve for y to transform the integrand u + 2v = 3y =rArr y = 13 (u + 2v) and computeintint

Ry2 dx dy =

intintS

(u + 2v)2

32

∣∣∣∣ part(x y)part(u v)

∣∣∣∣ du dv =int 6

0

int 12

0

(u + 2v)2

32 middot∣∣∣∣ 1minus6

∣∣∣∣ du dv

=154

int 6

0

int 12

0(u + 2v)2 du dv = 224

11

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 12: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Polar co-ordinates The usual formula for converting an integral to polar co-ordinates has the sameJacobian origin x = r cos θ y = r sin θ have Jacobian

part(x y)part(r θ)

=

∣∣∣∣xr xθ

yr yθ

∣∣∣∣ = ∣∣∣∣cos θ minusr sin θsin θ r cos θ

∣∣∣∣ = r cos2 θ + r sin2 θ = r

=rArrintint

Rf (x y)dx dy =

intintS

f (r cos θ r sin θ)r dr dθ

We can also convert the other way r =radic

x2 + y2 θ = tanminus1 yx yields

part(r θ)

part(x y)=

∣∣∣∣rx ryθx θy

∣∣∣∣ =∣∣∣∣∣

xradicx2+y2

yradicx2+y2

minusyx2+y2

xx2+y2

∣∣∣∣∣ = x2 + y2

(x2 + y2)radic

x2 + y2=

1radicx2 + y2

=rArrintint

Rf (r θ)dr dθ =

intintS

f(radic

x2 + y2 tanminus1 yx

)1radic

x2 + y2dx dy

Change of Variables in Triple Integration The idea is identical to that for double integrals wesimply need a Jacobian for three variables

Definition Let (x y z) = (x(u v w) y(u v w) z(u v w)) be a transformation of co-ordinatesThe Jacobian of the transformation is

part(x y z)part(u v w)

=

∣∣∣∣∣∣xu xv xwyu yv ywzu zv zw

∣∣∣∣∣∣ =xu

yuzu

middotxv

yvzv

timesxw

ywzw

Example If x = vminus w y = minusu + w and z = uminus 2v then

part(x y z)part(u v w)

=

∣∣∣∣∣∣0 1 minus1minus1 0 11 minus2 0

∣∣∣∣∣∣ = 0minus11

middot2

21

= minus1

Theorem Suppose S is region of (u v w)-space mapped 1ndash1 onto a region R in (x y z)-space by a transfor-mation (x y z) = T(u v w) with continuous 1st partial derivatives If f is continuous on R thenintintint

Rf (x y z)dx dy dz =

intintintS

f (T(u v w))

∣∣∣∣ part(x y z)part(u v w)

∣∣∣∣du dv dw

Just as for polar co-ordinates we can use this method to derive other change of variable formulaelig

Cylindrical Polar Co-ordinates x = r cos θ y = r sin θ z = z gives

part(x y z)part(r θ z)

=

∣∣∣∣∣∣cos θ minusr sin θ 0sin θ r cos θ 0

0 0 1

∣∣∣∣∣∣ = r =rArr dV = r dr dθ dz

12

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10
Page 13: 15 Multiple Integrals - UCI Mathematicsndonalds/math2e/chapter15.pdf · 15.7 Triple Integrals Interpretation: If E is a region in two-dimensions and f is an integrable function on

Spherical Polar Co-ordinates

xyz

=

ρ sin φ cos θρ sin φ sin θ

ρ cos φ

gives

part(x y z)part(ρ φ θ)

=

∣∣∣∣∣∣xρ xφ xθ

yρ yφ yθ

zρ zφ zθ

∣∣∣∣∣∣ =∣∣∣∣∣∣sin φ cos θ ρ cos φ cos θ minusρ sin φ sin θsin φ sin θ ρ cos φ sin θ ρ sin φ cos θ

cos φ minusρ sin φ 0

∣∣∣∣∣∣=

sin φ cos θsin φ sin θ

cos φ

middotρ2 sin2 φ cos θ

ρ2 sin2 φ sin θρ2 sin φ cos φ

= ρ2 sin φ(sin2 φ cos2 θ + sin2 φ sin2 θ + cos2 φ)

= ρ2 sin φ

Since sin φ ge 0 for the allowed range of spherical co-ordinates (0 le φ le π) we conclude that

dV = ρ2 sin φ dρ dθ dφ

The Volume of an Ellipsoid Finally consider applying achange of co-ordinates to compute the volume of a generalellipsoid

x2

a2 +y2

b2 +z2

c2 = 1

We could employ a brute force approach in Cartesian co-ordinates since an ellipsoid has eight oc-tants each with the same volume we could compute

V = 8int a

0

int bradic

1minusx2a2

0cradic

1minus x2a2 minus y2b2 dy dx

Continuing from here requires a tricky trig substitution let y = bradic

1minus x2a2 sin θ so that dy =bradic

1minus x2a2 cos θ dθ and

V = 8bcint a

0

int π2

0(1minus x2a2) cos2 θ dθ dx = middot middot middot = 4

3πabc

A much simpler approach involves changing co-ordinates so that the ellipsoid becomes a sphereSince we know the volume of a sphere the calculation becomes trivialLet x = au y = bv z = cw then

part(x y z)part(u v w)

=

a00

middot0

b0

times0

0c

= abc

In u v w co-ordinates the ellipsoid has equation u2 + v2 + w2 = 1 it has become a unit sphere If Eis the solid ellipsoid and S the solid sphere then

V =intintint

Edx dy dz =

intintintS

abc du dv dw = abc middotVolume(S) =43

πabc

13

(C) 2012--today Alexander Grahn 3Dmenujs version 20131204 3D JavaScript used by media9sty Extended functionality of the (right click) context menu of 3D annotations 1) Adds the following items to the 3D context menu `Generate Default View Finds good default camera settings returned as options for use with the includemedia command `Get Current View Determines camera cross section and part settings of the current view returned as `VIEW section that can be copied into a views file of additional views The views file is inserted using the `3Dviews option of includemedia `Cross Section Toggle switch to add or remove a cross section into or from the current view The cross section can be moved in the x y z directions using x y z and X Y Z keys on the keyboard be tilted against and spun around the upright Z axis using the UpDown and LeftRight arrow keys and caled using the s and S keys 2) Enables manipulation of position and orientation of indiviual parts and groups of parts in the 3D scene Parts which have been selected with the mouse can be scaled moved around and rotated like the cross section as described above To spin the parts around their local up-axis keep Control key pressed while using the UpDown and LeftRight arrow keys This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahn The code borrows heavily from Bernd Gaertners `Miniball software originally written in C++ for computing the smallest enclosing ball of a set of points see httpwwwinfethzchpersonalgaertnerminiballhtmlhostconsoleshow()constructor for doubly linked listfunction List() thisfirst_node=null thislast_node=new Node(undefined)Listprototypepush_back=function(x) var new_node=new Node(x) if(thisfirst_node==null) thisfirst_node=new_node new_nodeprev=null else new_nodeprev=thislast_nodeprev new_nodeprevnext=new_node new_nodenext=thislast_node thislast_nodeprev=new_nodeListprototypemove_to_front=function(it) var node=itget() if(nodenext=null ampamp nodeprev=null) nodenextprev=nodeprev nodeprevnext=nodenext nodeprev=null nodenext=thisfirst_node thisfirst_nodeprev=node thisfirst_node=node Listprototypebegin=function() var i=new Iterator() itarget=thisfirst_node return(i)Listprototypeend=function() var i=new Iterator() itarget=thislast_node return(i)function Iterator(it) if( it=undefined ) thistarget=ittarget else thistarget=null Iteratorprototypeset=function(it)thistarget=ittargetIteratorprototypeget=function()return(thistarget)Iteratorprototypederef=function()return(thistargetdata)Iteratorprototypeincr=function() if(thistargetnext=null) thistarget=thistargetnextconstructor for node objects that populate the linked listfunction Node(x) thisprev=null thisnext=null thisdata=xfunction sqr(r)return(rr)helper functionMiniball algorithm by B Gaertnerfunction Basis() thism=0 thisq0=new Array(3) thisz=new Array(4) thisf=new Array(4) thisv=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisa=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thisc=new Array(new Array(3) new Array(3) new Array(3) new Array(3)) thissqr_r=new Array(4) thiscurrent_c=thisc[0] thiscurrent_sqr_r=0 thisreset()Basisprototypecenter=function()return(thiscurrent_c)Basisprototypesize=function()return(thism)Basisprototypepop=function()--thismBasisprototypeexcess=function(p) var e=-thiscurrent_sqr_r for(var k=0klt3++k) e+=sqr(p[k]-thiscurrent_c[k]) return(e)Basisprototypereset=function() thism=0 for(var j=0jlt3++j) thisc[0][j]=0 thiscurrent_c=thisc[0] thiscurrent_sqr_r=-1Basisprototypepush=function(p) var i j var eps=1e-32 if(thism==0) for(i=0ilt3++i) thisq0[i]=p[i] for(i=0ilt3++i) thisc[0][i]=thisq0[i] thissqr_r[0]=0 else for(i=0ilt3++i) thisv[thism][i]=p[i]-thisq0[i] for(i=1iltthism++i) thisa[thism][i]=0 for(j=0jlt3++j) thisa[thism][i]+=thisv[i][j]thisv[thism][j] thisa[thism][i]=(2thisz[i]) for(i=1iltthism++i) for(j=0jlt3++j) thisv[thism][j]-=thisa[thism][i]thisv[i][j] thisz[thism]=0 for(j=0jlt3++j) thisz[thism]+=sqr(thisv[thism][j]) thisz[thism]=2 if(thisz[thism]ltepsthiscurrent_sqr_r) return(false) var e=-thissqr_r[thism-1] for(i=0ilt3++i) e+=sqr(p[i]-thisc[thism-1][i]) thisf[thism]=ethisz[thism] for(i=0ilt3++i) thisc[thism][i]=thisc[thism-1][i]+thisf[thism]thisv[thism][i] thissqr_r[thism]=thissqr_r[thism-1]+ethisf[thism]2 thiscurrent_c=thisc[thism] thiscurrent_sqr_r=thissqr_r[thism] ++thism return(true)function Miniball() thisL=new List() thisB=new Basis() thissupport_end=new Iterator()Miniballprototypemtf_mb=function(it) var i=new Iterator(it) thissupport_endset(thisLbegin()) if((thisBsize())==4) return for(var k=new Iterator(thisLbegin())kget()=iget()) var j=new Iterator(k) kincr() if(thisBexcess(jderef()) gt 0) if(thisBpush(jderef())) thismtf_mb(j) thisBpop() if(thissupport_endget()==jget()) thissupport_endincr() thisLmove_to_front(j) Miniballprototypecheck_in=function(b) thisLpush_back(b)Miniballprototypebuild=function() thisBreset() thissupport_endset(thisLbegin()) thismtf_mb(thisLend())Miniballprototypecenter=function() return(thisBcenter())Miniballprototyperadius=function() return(Mathsqrt(thisBcurrent_sqr_r))functions called by menu itemsfunction calc3Dopts () create Miniball object var mb=new Miniball() auxiliary vector var corner=new Vector3() iterate over all visible mesh nodes in the scene for(i=0iltscenemeshescounti++) var mesh=scenemeshesgetByIndex(i) if(meshvisible) continue local to parent transformation matrix var trans=meshtransform build local to world transformation matrix by recursively multiplying the parents transf matrix on the right var parent=meshparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent get the bbox of the mesh (local coordinates) var bbox=meshcomputeBoundingBox() transform the local bounding box corner coordinates to world coordinates for bounding sphere determination BBoxmin cornerset(bboxmin) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) BBoxmax cornerset(bboxmax) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) remaining six BBox corners cornerset(bboxminx bboxmaxy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxminx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxminy bboxmaxz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) cornerset(bboxmaxx bboxmaxy bboxminz) cornerset(transtransformPosition(corner)) mbcheck_in(new Array(cornerx cornery cornerz)) compute the smallest enclosing bounding sphere mbbuild() current camera settings var camera=scenecamerasgetByIndex(0) var res= initialize result string aperture angle of the virtual camera (perspective projection) or orthographic scale (orthographic projection) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf(n3Daac=s aac) else cameraviewPlaneSize=2mbradius() res+=hostutilprintf(n3Dortho=s 1cameraviewPlaneSize) camera roll var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf(n3Droll=sroll) target to camera vector var c2c=new Vector3() c2cset(cameraposition) c2csubtractInPlace(cameratargetPosition) c2cnormalize() if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf(n3Dc2c=s s s c2cx c2cy c2cz) new camera settings bounding sphere centre --gt new camera target var coo=new Vector3() cooset((mbcenter())[0] (mbcenter())[1] (mbcenter())[2]) if(coolength) res+=hostutilprintf(n3Dcoo=s s s coox cooy cooz) radius of orbit if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var roo=mbradius() Mathsin(aac MathPI 360) else orthographic projection var roo=mbradius() res+=hostutilprintf(n3Droo=s roo) update camera settings in the viewer var currol=cameraroll cameratargetPositionset(coo) camerapositionset(cooadd(c2cscale(roo))) cameraroll=currol determine background colour rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf(n3Dbg=s s s rgbr rgbg rgbb) determine lighting scheme switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+=hostutilprintf(n3Dlights=s curlights) determine global render mode switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak if(currender=Solid) res+=hostutilprintf(n3Drender=s currender) write result string to the console hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Copy and paste the following text to then+ option list of includemedian + res + n)function get3Dview () var camera=scenecamerasgetByIndex(0) var coo=cameratargetPosition var c2c=camerapositionsubtract(coo) var roo=c2clength c2cnormalize() var res=VIEW=insert optional name heren if((coox==0 ampamp cooy==0 ampamp cooz==0)) res+=hostutilprintf( COO=s s sn coox cooy cooz) if((c2cx==0 ampamp c2cy==-1 ampamp c2cz==0)) res+=hostutilprintf( C2C=s s sn c2cx c2cy c2cz) if(roo gt 1e-9) res+=hostutilprintf( ROO=sn roo) var roll = cameraroll180MathPI if(hostutilprintf(4f roll)=0) res+=hostutilprintf( ROLL=sn roll) if(cameraprojectionType==cameraTYPE_PERSPECTIVE) var aac=camerafov 180MathPI if(hostutilprintf(4f aac)=30) res+=hostutilprintf( AAC=sn aac) else if(hostutilprintf(4f cameraviewPlaneSize)=1) res+=hostutilprintf( ORTHO=sn 1cameraviewPlaneSize) rgb=scenebackgroundgetColor() if((rgbr==1 ampamp rgbg==1 ampamp rgbb==1)) res+=hostutilprintf( BGCOLOR=s s sn rgbr rgbg rgbb) switch(scenelightScheme) case sceneLIGHT_MODE_FILE curlights=Artworkbreak case sceneLIGHT_MODE_NONE curlights=Nonebreak case sceneLIGHT_MODE_WHITE curlights=Whitebreak case sceneLIGHT_MODE_DAY curlights=Daybreak case sceneLIGHT_MODE_NIGHT curlights=Nightbreak case sceneLIGHT_MODE_BRIGHT curlights=Hardbreak case sceneLIGHT_MODE_RGB curlights=Primarybreak case sceneLIGHT_MODE_BLUE curlights=Bluebreak case sceneLIGHT_MODE_RED curlights=Redbreak case sceneLIGHT_MODE_CUBE curlights=Cubebreak case sceneLIGHT_MODE_CAD curlights=CADbreak case sceneLIGHT_MODE_HEADLAMP curlights=Headlampbreak if(curlights=Artwork) res+= LIGHTS=+curlights+n switch(scenerenderMode) case sceneRENDER_MODE_BOUNDING_BOX defaultrender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX defaultrender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE defaultrender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES defaultrender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES defaultrender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME defaultrender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME defaultrender=ShadedWireframebreak case sceneRENDER_MODE_SOLID defaultrender=Solidbreak case sceneRENDER_MODE_TRANSPARENT defaultrender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME defaultrender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME defaultrender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION defaultrender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE defaultrender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION defaultrender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME defaultrender=HiddenWireframebreak if(defaultrender=Solid) res+= RENDERMODE=+defaultrender+n detect existing Clipping Plane (3D Cross Section) var clip=null if( clip=scenenodesgetByName($$$$$$)|| clip=scenenodesgetByName(Clipping Plane) ) for(var i=0iltscenenodescounti++) var nd=scenenodesgetByIndex(i) if(nd==clip||ndname==) continue var ndUTFName= for (var j=0 jltndnamelength j++) var theUnicode = ndnamecharCodeAt(j)toString(16) while (theUnicodelengthlt4) theUnicode = 0 + theUnicode ndUTFName += theUnicode var end=ndnamelastIndexOf() if(endgt0) var ndUserName=ndnamesubstr(0end) else var ndUserName=ndname respart= PART=+ndUserName+n respart+= UTF16NAME=+ndUTFName+n defaultvals=true if(ndvisible) respart+= VISIBLE=falsen defaultvals=false if(ndopacitylt10) respart+= OPACITY=+ndopacity+n defaultvals=false if(ndconstructorname==Mesh) currender=defaultrender switch(ndrenderMode) case sceneRENDER_MODE_BOUNDING_BOX currender=BoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX currender=TransparentBoundingBoxbreak case sceneRENDER_MODE_TRANSPARENT_BOUNDING_BOX_OUTLINE currender=TransparentBoundingBoxOutlinebreak case sceneRENDER_MODE_VERTICES currender=Verticesbreak case sceneRENDER_MODE_SHADED_VERTICES currender=ShadedVerticesbreak case sceneRENDER_MODE_WIREFRAME currender=Wireframebreak case sceneRENDER_MODE_SHADED_WIREFRAME currender=ShadedWireframebreak case sceneRENDER_MODE_SOLID currender=Solidbreak case sceneRENDER_MODE_TRANSPARENT currender=Transparentbreak case sceneRENDER_MODE_SOLID_WIREFRAME currender=SolidWireframebreak case sceneRENDER_MODE_TRANSPARENT_WIREFRAME currender=TransparentWireframebreak case sceneRENDER_MODE_ILLUSTRATION currender=Illustrationbreak case sceneRENDER_MODE_SOLID_OUTLINE currender=SolidOutlinebreak case sceneRENDER_MODE_SHADED_ILLUSTRATION currender=ShadedIllustrationbreak case sceneRENDER_MODE_HIDDEN_WIREFRAME currender=HiddenWireframebreak case sceneRENDER_MODE_DEFAULT currender=Defaultbreak if(currender=defaultrender) respart+= RENDERMODE=+currender+n defaultvals=false if(origtrans[ndname]ampampndtransformisEqual(origtrans[ndname])) var lvec=ndtransformtransformDirection(new Vector3(100)) var uvec=ndtransformtransformDirection(new Vector3(010)) var vvec=ndtransformtransformDirection(new Vector3(001)) respart+= TRANSFORM= +lvecx+ +lvecy+ +lvecz+ +uvecx+ +uvecy+ +uvecz+ +vvecx+ +vvecy+ +vvecz+ +ndtransformtranslationx+ +ndtransformtranslationy+ +ndtransformtranslationz+n defaultvals=false respart+= ENDn if(defaultvals) res+=respart if(clip) var centre=cliptransformtranslation var normal=cliptransformtransformDirection(new Vector3(001)) res+= CROSSSECTn if((centrex==0 ampamp centrey==0 ampamp centrez==0)) res+=hostutilprintf( CENTER=s s sn centrex centrey centrez) if((normalx==1 ampamp normaly==0 ampamp normalz==0)) res+=hostutilprintf( NORMAL=s s sn normalx normaly normalz) res+= ENDn res+=ENDn hostconsoleshow() hostconsoleclear() hostconsoleprintln(n Add the following VIEW section to a file ofn+ predefined views (See option 3Dviews)nn + The view may be given a name after VIEW=n + (Remove in front of =)n) hostconsoleprintln(res + n)add items to 3D context menuruntimeaddCustomMenuItem(dfltview Generate Default View default 0)runtimeaddCustomMenuItem(currview Get Current View default 0)runtimeaddCustomMenuItem(csection Cross Section checked 0)menu event handlersmenuEventHandler = new MenuEventHandler()menuEventHandleronEvent = function(e) switch(emenuItemName) case dfltview calc3Dopts() break case currview get3Dview() break case csection addremoveClipPlane(emenuItemChecked) break runtimeaddEventHandler(menuEventHandler)global variable taking reference to currently selected nodevar target=nullselectionEventHandler=new SelectionEventHandler()selectionEventHandleronEvent=function(e) if(eselectedampampenodename=) target=enode else target=null runtimeaddEventHandler(selectionEventHandler)cameraEventHandler=new CameraEventHandler()cameraEventHandleronEvent=function(e) var clip=null runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 0) if(clip=scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane)) runtimeremoveCustomMenuItem(csection) runtimeaddCustomMenuItem(csection Cross Section checked 1) if(clip)plane in predefined views must be rotated by 90 deg around normal cliptransformrotateAboutLineInPlace( MathPI2cliptransformtranslation cliptransformtransformDirection(new Vector3(001)) ) for(var i=0 iltrot4x4length i++)rot4x4[i]setIdentity() target=nullruntimeaddEventHandler(cameraEventHandler)var rot4x4=new Array() keeps track of spin and tilt axes transformationskey event handler for scaling moving spinning and tilting objectskeyEventHandler=new KeyEventHandler()keyEventHandleronEvent=function(e) var backtrans=new Matrix4x4() var trgt=null if(target) trgt=target var backtrans=new Matrix4x4() var trans=trgttransform var parent=trgtparent while(parenttransform) build local to world transformation matrix transmultiplyInPlace(parenttransform) also build world to local back-transformation matrix backtransmultiplyInPlace(parenttransforminversetranspose) parent=parentparent backtranstransposeInPlace() else if( trgt=scenenodesgetByName($$$$$$)|| trgt=scenenodesgetByName(Clipping Plane) ) var trans=trgttransform if(trgt) return var tname=trgtname if(typeof(rot4x4[tname])==undefined) rot4x4[tname]=new Matrix4x4() if(target) var tiltAxis=rot4x4[tname]transformDirection(new Vector3(010)) else var tiltAxis=transtransformDirection(new Vector3(010)) var spinAxis=rot4x4[tname]transformDirection(new Vector3(001)) get the centre of the mesh if(targetampamptrgtconstructorname==Mesh) var centre=transtransformPosition(trgtcomputeBoundingBox()center) else part group (Node3 parent node clipping plane) var centre=new Vector3(transtranslation) switch(echaracterCode) case 30tilt up rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(-MathPI900centretiltAxis) break case 31tilt down rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationtiltAxis) transrotateAboutLineInPlace(MathPI900centretiltAxis) break case 28spin right if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(-MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( -MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(-MathPI900centrenew Vector3(001)) break case 29spin left if(ectrlKeyDownampamptarget) transrotateAboutLineInPlace(MathPI900centrespinAxis) else rot4x4[tname]rotateAboutLineInPlace( MathPI900rot4x4[tname]translationnew Vector3(001)) transrotateAboutLineInPlace(MathPI900centrenew Vector3(001)) break case 120 x translateTarget(trans new Vector3(100) e) break case 121 y translateTarget(trans new Vector3(010) e) break case 122 z translateTarget(trans new Vector3(001) e) break case 88 shift + x translateTarget(trans new Vector3(-100) e) break case 89 shift + y translateTarget(trans new Vector3(0-10) e) break case 90 shift + z translateTarget(trans new Vector3(00-1) e) break case 115 s transtranslateInPlace(centrescale(-1)) transscaleInPlace(101) transtranslateInPlace(centrescale(1)) break case 83 shift + s transtranslateInPlace(centrescale(-1)) transscaleInPlace(1101) transtranslateInPlace(centrescale(1)) break transmultiplyInPlace(backtrans)runtimeaddEventHandler(keyEventHandler)translates object by amount calculated from Canvas sizefunction translateTarget(t d e) var cam=scenecamerasgetByIndex(0) if(camprojectionType==camTYPE_PERSPECTIVE) var scale=Mathtan(camfov2) camtargetPositionsubtract(camposition)length Mathmin(ecanvasPixelWidthecanvasPixelHeight) else var scale=camviewPlaneSize2 Mathmin(ecanvasPixelWidthecanvasPixelHeight) ttranslateInPlace(dscale(scale))function addremoveClipPlane(chk) var curTrans=getCurTrans() var clip=scenecreateClippingPlane() if(chk) add Clipping Plane and place its center either into the camera target position or into the centre of the currently selected mesh node var centre=new Vector3() if(target) var trans=targettransform var parent=targetparent while(parenttransform) trans=transmultiply(parenttransform) parent=parentparent if(targetconstructorname==Mesh) var centre=transtransformPosition(targetcomputeBoundingBox()center) else var centre=new Vector3(transtranslation) target=null else centreset(scenecamerasgetByIndex(0)targetPosition) cliptransformsetView( new Vector3(000) new Vector3(100) new Vector3(010)) cliptransformtranslateInPlace(centre) else if( scenenodesgetByName($$$$$$)|| scenenodesgetByName(Clipping Plane) ) clipremove() restoreTrans(curTrans)function to store current transformation matrix of all nodes in the scenefunction getCurTrans() var tA=new Array() for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(ndname==) continue tA[ndname]=new Matrix4x4(ndtransform) return tAfunction to restore transformation matrices given as argfunction restoreTrans(tA) for(var i=0 iltscenenodescount i++) var nd=scenenodesgetByIndex(i) if(tA[ndname]) ndtransformset(tA[ndname]) store original transformation matrix of all mesh nodes in the scenevar origtrans=getCurTrans()set initial state of Cross Section menu entrycameraEventHandleronEvent(1)hostconsoleclear()

var ocgs=hostgetOCGs(hostpageNum)for(var i=0iltocgslengthi++)if(ocgs[i]name==MediaPlayButton10)ocgs[i]state=false

(C) 2012 Michail Vidiassov John C Bowman Alexander Grahn asylabelsjs version 20120912 3D JavaScript to be used with media9sty (option `add3Djscript) for Asymptote generated PRC files adds billboard behaviour to text labels in Asymptote PRC files so that they always face the camera under 3D rotation This work may be distributed andor modified under the conditions of the LaTeX Project Public License either version 13 of this license or (at your option) any later version The latest version of this license is in httpwwwlatex-projectorglppltxt and version 13 or later is part of all distributions of LaTeX version 20051201 or later This work has the LPPL maintenance status `maintained The Current Maintainer of this work is A Grahnvar bbnodes=new Array() billboard meshesvar bbtrans=new Array() billboard transformsfunction fulltransform(mesh) var t=new Matrix4x4(meshtransform) if(meshparentname = ) var parentTransform=fulltransform(meshparent) tmultiplyInPlace(parentTransform) return t else return t find all text labels in the scene and determine pivoting pointsvar nodes=scenenodesvar nodescount=nodescountvar third=1030for(var i=0 i lt nodescount i++) var node=nodesgetByIndex(i) var name=nodename var end=namelastIndexOf()-1 if(end gt 0) if(namecharAt(end) == 001) var start=namelastIndexOf(-)+1 if(end gt start) nodename=namesubstr(0start-1) var nodeMatrix=fulltransform(nodeparent) var c=nodeMatrixtranslation position var d=Mathpow(Mathabs(nodeMatrixdeterminant)third) scale bbnodespush(node) bbtranspush(Matrix4x4()scale(ddd)translate(c)multiply(nodeMatrixinverse)) var camera=scenecamerasgetByIndex(0) var zero=new Vector3(000)var bbcount=bbnodeslength event handler to maintain camera-facing text labelsbillboardHandler=new RenderEventHandler()billboardHandleronEvent=function(event) var T=new Matrix4x4() TsetView(zerocamerapositionsubtract(cameratargetPosition) cameraupsubtract(cameraposition)) for(var j=0 j lt bbcount j++) bbnodes[j]transformset(Tmultiply(bbtrans[j])) runtimerefresh() runtimeaddEventHandler(billboardHandler)runtimerefresh()

  • Multiple Integrals
    • Iterated Integrals
    • Double Integrals over General Regions
    • Double Integrals in Polar Co-ordinates
    • Triple Integrals
    • Triple Integrals in Cylindrical Co-ordinates
    • Triple Integrals in Spherical Co-ordinates
    • Change of Variables in Multiple Integrals
          1. fdrm0
          2. fdrm1
          3. fdrm2
          4. fdrm3
          5. fdrm4
          6. fdrm5
          7. fdrm6
          8. fdrm7
          9. fdrm8
          10. fdrm9
          11. fdrm10