|
| 1 | +<head> |
| 2 | +<meta charset=utf-8> |
| 3 | +<script type="text/javascript" src="glutil_min.js"></script> |
| 4 | +<script type="text/javascript" src="camera.js"></script> |
| 5 | +</head> |
| 6 | +<body> |
| 7 | +<a href="javascript:link1()">Ellipsoid</a>, |
| 8 | +<a href="javascript:link2()">Klein bottle</a>, |
| 9 | +<a href="javascript:link3()">Möbius strip</a> |
| 10 | +<br> |
| 11 | +<canvas width="600" height="450" id=canvas></canvas> |
| 12 | +<script id="demo"> |
| 13 | +//<!-- |
| 14 | +/* |
| 15 | +Written by Peter O. in 2015. |
| 16 | +
|
| 17 | +Any copyright is dedicated to the Public Domain. |
| 18 | +http://creativecommons.org/publicdomain/zero/1.0/ |
| 19 | +If you like this, you should donate to Peter O. |
| 20 | +at: http://upokecenter.dreamhosters.com/articles/donate-now-2/ |
| 21 | +*/ |
| 22 | + |
| 23 | +var Ellipsoid=function(xRadius, yRadius, zRadius){ |
| 24 | + this.xRadius=xRadius; |
| 25 | + this.yRadius=yRadius; |
| 26 | + this.zRadius=zRadius; |
| 27 | + this.evaluate=function(u,v,output){ |
| 28 | + u*=Math.PI*2; |
| 29 | + v*=Math.PI; |
| 30 | + output[0]=Math.cos(v)*Math.cos(u)*this.xRadius; |
| 31 | + output[1]=Math.sin(v)*Math.cos(u)*this.yRadius; |
| 32 | + output[2]=Math.sin(u)*this.zRadius; |
| 33 | + return 3; |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +var KleinBottle=function(){ |
| 38 | + this.evaluate=function(u,v,output){ |
| 39 | + u*=Math.PI*2; |
| 40 | + v*=Math.PI*2; |
| 41 | + var x, y, z; |
| 42 | + var sinu=Math.sin(u); |
| 43 | + var sinv=Math.sin(v); |
| 44 | + var cosu=Math.cos(u); |
| 45 | + var cosv=Math.cos(v); |
| 46 | + if(u<Math.PI){ |
| 47 | + x = 3 * cosu * (1 + sinu) + (2 * (1 - cosu / 2)) * cosu * cosv; |
| 48 | + z = -8 * sinu - 2 * (1 - cosu / 2) * sinu * cosv; |
| 49 | + } else { |
| 50 | + x = 3 * cosu * (1 + sinu) + (2 * (1 - cosu / 2)) * Math.cos(v + Math.PI) |
| 51 | + z = -8 * sinu |
| 52 | + } |
| 53 | + y = -2 * (1 - cosu / 2) * sinv; |
| 54 | + output[0]=x/6; |
| 55 | + output[1]=z/6; |
| 56 | + output[2]=y/6; |
| 57 | + return 3; |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +var MoebiusStrip=function(maj, a, b){ |
| 62 | + this.maj=maj==null ? 1.25 : maj |
| 63 | + this.a=a==null ? 0.125 : a |
| 64 | + this.b=b==null ? 0.5 : b |
| 65 | + this.evaluate=function(u,v,output){ |
| 66 | + u*=Math.PI; |
| 67 | + v*=Math.PI*2; |
| 68 | + u=-u |
| 69 | + var x, y, z; |
| 70 | + var sinu=Math.sin(u); |
| 71 | + var sinv=Math.sin(v); |
| 72 | + var cosu=Math.cos(u); |
| 73 | + var cosv=Math.cos(v); |
| 74 | + x = this.a * cosv * cosu - this.b * sinv * sinu |
| 75 | + z = this.a * cosv * sinu + this.b * sinv * cosu |
| 76 | + y = (this.maj + x) * Math.sin(u*2) |
| 77 | + x = (this.maj + x) * Math.cos(u*2) |
| 78 | + output[0]=x; |
| 79 | + output[1]=z; |
| 80 | + output[2]=y; |
| 81 | + return 3; |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +var ColorGradient={ |
| 88 | +evaluate:function(u,v,output){ |
| 89 | + output[0]=1.0-u; |
| 90 | + output[1]=v; |
| 91 | + output[2]=u; |
| 92 | + return 3; |
| 93 | +} |
| 94 | +} |
| 95 | + |
| 96 | +function makeMesh(func){ |
| 97 | + var mesh=new Mesh(); |
| 98 | + var ev=new SurfaceEval() |
| 99 | + .vertex(func) |
| 100 | + .color(ColorGradient) |
| 101 | + .setAutoNormal(true) |
| 102 | + .evalSurface(mesh,Mesh.TRIANGLES,50,50); |
| 103 | + console.log(mesh) |
| 104 | + return mesh; |
| 105 | +} |
| 106 | + |
| 107 | +function link1(){ |
| 108 | + if(shape)scene.removeShape(shape); |
| 109 | + scene.addShape(shape=scene.makeShape(makeMesh(new Ellipsoid(0.8,0.4,0.8)))); |
| 110 | +} |
| 111 | + |
| 112 | +function link2(){ |
| 113 | + scene.removeShape(shape); |
| 114 | + scene.addShape(shape=scene.makeShape(makeMesh(new KleinBottle()))); |
| 115 | +} |
| 116 | + |
| 117 | +function link3(){ |
| 118 | + scene.removeShape(shape); |
| 119 | + scene.addShape(shape=scene.makeShape(makeMesh(new MoebiusStrip()))); |
| 120 | +} |
| 121 | + |
| 122 | + |
| 123 | + // Create the 3D scene; find the HTML canvas and pass it |
| 124 | + // to Scene3D. |
| 125 | + var scene=new Scene3D(document.getElementById("canvas")); |
| 126 | + var camera=new Camera(scene,45,1,100); |
| 127 | + camera.setDistance(5); |
| 128 | + var shape=null; |
| 129 | + link1(); |
| 130 | + scene.addShape(shape); |
| 131 | + GLUtil.renderLoop(function(){ |
| 132 | + camera.update(); |
| 133 | + scene.render(); |
| 134 | + }); |
| 135 | + |
| 136 | +//--> |
| 137 | +</script> |
| 138 | +<script> |
| 139 | +window.addEventListener("load",function(){ |
| 140 | + var e=document.createElement("pre") |
| 141 | + e.innerHTML=document.getElementById("demo").textContent.replace(/</g,"<") |
| 142 | + document.body.appendChild(e) |
| 143 | +}) |
| 144 | +</script> |
| 145 | +</body> |
0 commit comments