TWaver - 專注UI技術

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          TWaver3D拓撲圖之球花綻放

          Posted on 2016-11-23 10:32 TWaver 閱讀(325) 評論(0)  編輯  收藏


          這樣一簇絢爛豐滿艷麗多姿的3D小球花,要多少代碼才能完成?其實不足百行,您信嗎?下面咱就看一下具體實現過程,讓您分分鐘學會用TWaver HTML5制作3D拓撲圖。


          搭建3D空間

          首先為花簇的綻放建一個展示的舞臺。接觸過TWaver2D的都知道,box、network是必不可少的,但對3D場景來說,還遠遠不夠。一是要添加鏡頭位置,確定我們在什么角度和距離進行觀察;二是要加上燈光,否則再美的畫面也看不見。燈光分為點光源和環境光,一般來說要一個環境光和若干點光源搭配才能出來好的效果。

          var box = new mono.DataBox();
          var network
          = new mono.Network3D(box, null, monoCanvas);
          mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,
          'clientWidth','clientHeight');
          network.getCamera().setPosition(
          004000);
          network.isSelectable
          =function(){return false};
          network.setClearColor(
          'black');
          var pointLight 
          = new mono.PointLight(0xFFFFFF,0.8);
          box.add(pointLight);
          var pointLight 
          = new mono.PointLight(0xFFFFFF,0.5);
          pointLight.setPosition(
          500,2000,0);
          box.add(pointLight);
          box.add(
          new mono.AmbientLight(0x888888));

          創建3D小球花瓣


          每一個3D小球就是一個花瓣,是整個花簇的基礎部件,也是最容易做的,只要幾行代碼而已。


          function createNode(color){
            
          //var color = color || '#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6);
            var node=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
            node.s({
              
          'm.type''phong',
              
          'm.color': color,
              
          'm.ambient': color,
            });
            
          return node;
          }

          其中的BALL_SEGMENT是球體切片數量,數量越大生成的球體越圓滑,但計算量也就越大。解除注釋掉的那條語句將會每次生成一個隨機顏色的小球,這種五顏六色的感覺也別有趣味。


          生成3D花朵


          正如若干花瓣組成一朵小花,我們也要將若干個小球連接在一起。這一步最重要的是花瓣的排列,既要隨機有活力,又要規律有造型。實例中是將小球隨機排列在一個球面的局部。


          function getSpherePoint(r, angle1, angle2){
              var x
          =r*Math.sin(angle1)*Math.cos(angle2);
              var y
          =r*Math.cos(angle1);
              var z
          =r*Math.sin(angle1)*Math.sin(angle2);
              
          return new mono.Vec3(x, y, z);
          }

          有了花瓣的擺放位置,一朵花也就很容易開放了:

          function createTree(box, count, range, offset, color){
              var angleStep
          =Math.PI/50;
              var center
          =new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
              center.s({
                  
          'm.type''phong',
                  
          'm.color': color,
                  
          'm.ambient': color,
              });
              box.add(center);
              
          for(var i=0;i<count;i++){
                  var node
          = createNode(color);
                  var r
          =1000;
                  var angle1
          =range*Math.random()/5;
                  var angle2
          =Math.PI*2*Math.random();
                  var point
          =getSpherePoint(r, angle1, angle2);
                  point.y
          -=offset;
                  node.setPosition(point);
                  node.setParent(center);
                  box.add(node);
                  box.add(createLink(center, node));
              }
              
          return center;
          }

          通過改變其參數,可以開出不同的花朵。其中count是花瓣的數量,range是花朵球面的角度,offset是花瓣到花托的長度,color是花朵的顏色。


          綻放3D花簇

          剩下的工作就極其簡單了,先建一個中心小球,再通過兩個循環,就生成了有兩層花朵的球狀花簇。


          var center=createNode('red');
          box.add(center);
          for(var i=0;i<40;i++){
              var angle1
          =Math.random()*Math.PI;
              var angle2
          =Math.random()*Math.PI*2;
              var point
          =getSpherePoint(1000, angle1, angle2);
              var tree
          =createTree(box, 100, Math.PI*0.4800'yellow');
              tree.setPosition(point.x, point.y, point.z);
              var rotation
          =point.rotationTowards(new mono.Vec3(0,1,0), point);
              tree.setRotation(rotation);
              box.add(createLink(center, tree));
          }

          當然,你可以說這根本不像什么花簇。其實本來也不是要做一個現實的什么東西,只是為了用一段小而美的程序,讓大家領略TWaver3D拓撲圖的風采。如果您從中get到了什么技能和興趣,那才是我們的真正目的!

          實際上,這個例子稍作變化,就可以用來展示豐富的3D網絡拓撲圖、各種復雜數據的樹狀關系圖。你一定可以讓它綻放的更加美麗!


          為了證實代碼確實不足百行,特附上完整源碼:

           1 <!DOCTYPE html>
           2 <html>
           3 <head>
           4     <title>Mono Test</title>
           5     <script type="text/javascript" src = "t.js"></script>
           6     <script type="text/javascript">
           7         var BALL_SEGMENT=7;
           8         function init(){
           9             var box = new mono.DataBox();
          10             var network= new mono.Network3D(box, null, monoCanvas);
          11             mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight');
          12             network.getCamera().setPosition(004000);
          13             network.isSelectable=function(){return false};
          14             network.setClearColor('black');
          15             var pointLight = new mono.PointLight(0xFFFFFF,0.8);
          16             box.add(pointLight);
          17             var pointLight = new mono.PointLight(0xFFFFFF,0.5);
          18             pointLight.setPosition(500,2000,0);
          19             box.add(pointLight);
          20             box.add(new mono.AmbientLight(0x888888));
          21             var center=createNode('red');
          22             box.add(center);
          23             for(var i=0;i<10;i++){
          24                 var angle1=Math.random()*Math.PI;
          25                 var angle2=Math.random()*Math.PI*2;
          26                 var point=getSpherePoint(300, angle1, angle2);
          27                 var tree=createTree(box, 100, Math.PI*0.6700'#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6));
          28                 tree.setPosition(point.x, point.y, point.z);
          29                 var rotation=point.rotationTowards(new mono.Vec3(0,1,0), point);
          30                 tree.setRotation(rotation);
          31                 box.add(createLink(center, tree));
          32             }
          33             for(var i=0;i<40;i++){
          34                 var angle1=Math.random()*Math.PI;
          35                 var angle2=Math.random()*Math.PI*2;
          36                 var point=getSpherePoint(1000, angle1, angle2);
          37                 var tree=createTree(box, 100, Math.PI*0.4800);
          38                 tree.setPosition(point.x, point.y, point.z);
          39                 var rotation=point.rotationTowards(new mono.Vec3(0,1,0), point);
          40                 tree.setRotation(rotation);
          41                 box.add(createLink(center, tree));
          42             }
          43         }
          44         function createTree(box, count, range, offset, color){
          45             var angleStep=Math.PI/50;
          46             var center=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
          47             center.s({
          48                 'm.type''phong',
          49                 'm.color': color,
          50                 'm.ambient': color,
          51             });
          52             box.add(center);
          53             for(var i=0;i<count;i++){
          54                 var node= createNode(color);
          55                 var r=1000;
          56                 var angle1=range*Math.random()/5;
          57                 var angle2=Math.PI*2*Math.random();
          58                 var point=getSpherePoint(r, angle1, angle2);
          59                 point.y-=offset;
          60                 node.setPosition(point);
          61                 node.setParent(center);
          62                 box.add(node);
          63                 box.add(createLink(center, node));
          64             }
          65             return center;
          66         }
          67         function getSpherePoint(r, angle1, angle2){
          68             var x=r*Math.sin(angle1)*Math.cos(angle2);
          69             var y=r*Math.cos(angle1);
          70             var z=r*Math.sin(angle1)*Math.sin(angle2);
          71             return new mono.Vec3(x, y, z);
          72         }
          73         function createNode(color){
          74             var color = color || '#'+('00000'+(Math.random()*0x1000000<<0).toString(16)).slice(-6);
          75             var node=new mono.Sphere(10,BALL_SEGMENT,BALL_SEGMENT);
          76             node.s({
          77                 'm.type''phong',
          78                 'm.color': color,
          79                 'm.ambient': color,
          80             });
          81             return node;
          82         }
          83         function createLink(node1, node2){
          84             var link=new mono.Link(node1, node2);
          85             link.s({
          86                 'm.transparent'true,
          87                 'm.opacity'0.2,
          88             });
          89             return link;
          90         }     
          91     </script>
          92 </head>
          93 <body onload = 'init()'>
          94     <div>
          95         <canvas id="monoCanvas"/>
          96     </div>
          97 </body>
          98 </html>


          如有任何問題,可以留言,或者發郵件給我們:tw-service@servasoft.com。

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 双峰县| 南投市| 东宁县| 准格尔旗| 潜山县| 无棣县| 天柱县| 常宁市| 渭源县| 宿迁市| 宜州市| 庆城县| 额济纳旗| 津市市| 白朗县| 湘阴县| 丽水市| 时尚| 福贡县| 雅江县| 驻马店市| 海阳市| 荃湾区| 张家界市| 灌南县| 盐津县| 同江市| 定安县| 广宗县| 马龙县| 定襄县| 金乡县| 隆德县| 和平区| 古丈县| 孝昌县| 东安县| 丰都县| 遵义县| 邛崃市| 大新县|