LATEST ENTRIES
CATEGORIES
ARCHIVES
SPONSORED LINK
MOBILE
qrcode
LINKS
PROFILE
OTHERS

10
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--
>>
<<
--

Agata's Blog

MATLABやPythonとともにD3.jsを使ってデータ解析とデータビジュアライゼーションに挑戦する某エンジニアのBlog
<< 【D3.js】 リサージュ曲線 (Lissajous curve) を描画する | main | ツールチップの作成方法 >>
【D3.js】 バラ曲線 (Rose curve) を描画する
0
    JUGEMテーマ:JavaScript

    前回は D3.js を使って、プルダウンメニューで選択した数値によって変化するリサージュ曲線 (Lissajous curve) を描画しました。リサージュ曲線と同じように sin, cos を使った曲線として、バラ曲線 (Rose curve) があります。そこで今回は、このバラ曲線 (別名「正葉曲線」とも呼ばれます) を描画するプログラムを作成してみました。

    バラ曲線は、局座標表示で下式によって現される曲線です。

    r = sin((a/b)θ)

    とてもシンプルな方程式ですが、変数 a, b を変化させることで、驚くほど多様な変化を見せてくれます。

    前回リサージュ曲線を描画したときの html ファイルはそのまま流用して、JavaScript プログラムだけを下記のように変更します。変数 a, b を変化させて、ぜひバラ曲線が変化する様子を楽しんでみて下さい。

    サンプルページ



    // グラフの周囲にマージンを確保する
    var margin = {top: 40, right: 40, bottom: 80, left: 80};
    var width = 600 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    
    // SVGの表示領域を生成
    var svg = d3.select("#MyGraph")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
    
    var n = 2001;
    
    var dt = 20.0*Math.PI/n;
    var t = d3.range(0, 20.0*Math.PI, dt);
    var x = d3.range(n);
    var y = d3.range(n);
    
    // X軸のスケール関数を生成
    var x_scale = d3.scale.linear()
      .domain([-1, 1])
      .range([(width/2) - 200, (width/2) + 200]);
        
    // Y軸のスケール関数を生成
    var y_scale = d3.scale.linear()
      .domain([-1,1])
      .range([(height/2) - 200, (height/2) + 200]);  
      
    // (x,y) の軌跡を描画するための関数
    var line = d3.svg.line()
      .x(function(d, i){ return x_scale(x[i]);})
      .y(function(d, i) { return y_scale(y[i]);})
      .interpolate("linear");
    
    var polyline = svg.append('path')
      .attr("class", "line")
      .attr('stroke', 'black')
      .attr('stroke-width', '1')
      .attr('fill', 'transparent');
    
    // 初期値として a = 1, b = 1のグラフを描画
    update(1,1);
    updateLine();
    
    // 対象となる html 内のプルダウン要素を選択 
    var select_a = document.getElementById( 'listbox_a' );
    var select_b = document.getElementById( 'listbox_b' );
    
    var a = 1;
    var b = 1;
    
    // プルダウンメニューが更新されるとグラフを更新する
    select_a.onchange = function(){
      // プルダウンで選択されているoption要素を取得する
      var selectedItem = this.options[ this.selectedIndex ];
      a = selectedItem.value;
      update(a, b);
      updateLine();
    }
    
    select_b.onchange = function(){
      // プルダウンで選択されているoption要素を取得する
      var selectedItem = this.options[ this.selectedIndex ];
      b = selectedItem.value;
      update(a, b);
      updateLine();
    }
    
    // バラ曲線 (Rose curve) を計算する
    function update(a, b){
      for (var i = 0; i < n; i++){
        x[i] = Math.sin((a/b)*t[i])*Math.cos(t[i]);
        y[i] = Math.sin((a/b)*t[i])*Math.sin(t[i]);
      }
    }
    
    // バラ曲線を更新する
    function updateLine(){
      polyline
        .transition()
        .duration(1500)
        .ease("bounce")
        .attr('d', line(y));
    }
    
    // X軸を描画
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + height/2 + ")")
      .call(d3.svg
        .axis()
        .scale(x_scale)
        .orient("bottom")
      );
      
    // Y軸を描画
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + width/2 + ",0)")
      .call(d3.svg
        .axis()
        .scale(y_scale)
        .orient("left")
      );
      
    

     
    このエントリーをはてなブックマークに追加
    | アニメーション | 21:03 | comments(0) | - | - |
    スポンサーリンク