等高線グラフの回転 †
等高線グラフへ
ポリゴンモデル(メッシュ化) †
等高線グラフの元データはxy軸の平面座標上のz軸(高さ)の値です。このデータから構成される最少の図形は四角形ですが、この四角形は平面ではありません。この四角形の中がどのようになっているかはデータがないため不明です。また、この平面ではない四角形はAffine変換ができないため3D化に都合のいいAffin変換ができる三角形に分割し、これを平面として取扱います。ではどのように三角形に分割するかというと一番高い点とその対角の点を結んだ線で分割します。この線は他の2点の値により四角形の中で山線または谷線になります。
従って、ポリゴンモデルは碁盤目状の各マス目の4点の最大値を求めその対角点を結んだ線で分割して三角形を作ることになります。
等高線描画 †
等高線はポリゴンモデルで計算した各三角形の各辺(線)に対して等高線となる各高さ(面)との交点を計算し、他の辺の同じ高さの交点と直線で結びます。
等高線の面がx,y座標に対して平行なので交点の座標はx軸・y軸それぞれでz軸に対しての2次元座標として直線の交点の計算をする方法に単純化して求められます。
二点を通る直線の方程式 †
ポリゴン三角形の辺と等高線との交点はx-z座標の場合以下の図のようになります。
ここでp1(x1,z1)-p2(x2,z2)がポリゴン三角形の1辺でhが等高線の値です。Q(qx,qz)は交点です。x2-x1は2点間のx座標での距離、z2-z1は2点間のz座標での距離となります。
上図の2点を通る直線の式は以下となります。
z-z1 = ( (z2-z1)/(x2-x1) )・(x-x1)
これをz(高さ)からxを求める式に変形します。
x = ( (x2-x1)/(z2-z1) )・z + (x1・z2 -z1・x2)/(z2-z1)
この式を3次元の等高線(高さh)に対するx座標の計算式用にz → hにします。
また、y座標の計算式用にx1→y1、x2→y2とすると等高線(高さh)からx,y座標を求める以下の2式が得られます。
x = ( (x2-x1)/(z2-z1) )・h + (x1・z2 -z1・x2)/(z2-z1)
y = ( (y2-y1)/(z2-z1) )・h + (y1・z2 -z1・y2)/(z2-z1)
ここで係数
ax = (x2-x1)/(z2-z1), bx = (x1・z2 -z1・x2)/(z2-z1)
ay = (y2-y1)/(z2-z1), by = (y1・z2 -z1・y2)/(z2-z1)
とするとx,y座標を求める式は以下のようになります。
x = ax・h + bx
y = ay・h + by
採色 †
等高線の値により等高線間を段階的に色付けします。彩色するためには、等高線とポリゴンの辺ので囲まれた図形を描きその図形に色を設定します。結局は等高線と彩色した図形の2重書きとなります。この時彩色した図形の辺(Line)は無色で、こうすることによりポリゴンの辺と等高線が太くなりません。
彩色する形状は等高線とポリゴンの辺の状態で三角形、四角形、五角形のパターンがあり、等高線の状態により判断します。
等高線グラフの3D化 †
通常の方法であれば、前章の立方体のように各頂点、等高線とポリゴンの交点をアフィン変換して計算し値を書き換えますが、ここではSVGのアフィン変換の機能(Transform属性)を利用してポリゴン単位でアフィン変換し、等高線の計算を省略します。そのために等高線、彩色の図形はポリゴンのグループ内に作成します。こうすることによりポリゴンを変形するとグループ内の等高線と彩色の図形も一緒に変形されます。実は三角形であればアフィン変換に都合がいいのでポリゴンを三角形でメッシュ化したのです。
3D化は以下のようになります。
(1)等高線図を平面で作成します。
(2)各ポリゴンのアフィン変換後の座標を計算します。各ポリゴンの頂点の座標をポインターとして保持すれば、各頂点の座標は各ポリゴンごとではなく、元の図の点の座標の計算だけで済みます。
(3)平面図からアフィン変換後の座標に変換する2次元アフィン変換を求めます。この平面図からアフィン変換後の図が正しければいいので、実は元になる平面図は実際の座標に作成してなくてもいいのです。さらに言えば同じ大きさでなくてもいいです。(下図の描画用の平面図)
2次元アフィン変換は以下のようにして求められます。
SVGの図形変換transform属性のmatrix関数の各係数をa,b,c,d,e,fとすると、行列式は以下のようになります。
これを展開すると次の式になります。
x' = ax + cy + e
y' = bx + dy + f
ポリゴン三角形の平面図の各頂点の座標をp1(x1,y1),p1(x2,y2),p3(x3,y3)、変換後の座標をp'1(x'1,y'1),p'1(x'2,y'2),p'3(x'3,y'3)とすると上記の展開後の式から以下の6式が得られます。
x'1 = ax1 + cy1 + e
x'2 = ax2 + cy2 + e
x'3 = ax3 + cy3 + e
y'1 = bx1 + dy1 + f
y'2 = bx2 + dy2 + f
y'3 = bx3 + dy3 + f
上記をx,yとa,b,c,d,e,fの行列式にまとめると以下の2式となります。
ここで、
とすると上記の式は以下のようになります。
X = M・A
Y = M・B
これをAとBを求める式に変換すると
A = M-1・X
B = M-1・Y
となりMの逆行列を求めて計算することにより、係数a,b,c,d,e,fが求められます。3Dのための数学基礎の余因子行列と逆行列から逆行列を求める計算式を適用すると各係数は以下の式で求められます。
a = ((y2 - y3)x1' + (y3 - y1)x2' + (y1 - y2)x3') / |M|
c = ((x3 - x2)x1' + (x1 - x3)x2' + (x2 - x1)x3') / |M|
e = ((x2y3 - x3y2)x1' + (x3y1 - x1y3)x2' + (x1y2 - x2y1)x3') / |M|
b = ((y2 - y3)y1' + (y3 - y1)y2' + (y1 - y2)y3') / |M|
d = ((x3 - x2)y1' + (x1 - x3)y2' + (x2 - x1)y3') / |M|
f = ((x2y3 - x3y2)y1' + (x3y1 - x1y3)y2' + (x1y2 - x2y1)y3') / |M|
ここで|M|はMの行列式で以下の計算式となります。
|M| = x1y2 - x1y3 - x2y1 + x2y3 + x3y1 - x3y2
軸・目盛の表示 †
軸と目盛は平面の4辺の内奥側になる2辺に軸と目盛を表示するように、表示角度により判断して表示します。
目盛の表示で考慮点があります。SVGの座標系と表示する座標系が異なるため今まで表示してきた図形は実は最後に全体を上下を反転させる変換と原点を移動する変換をしています。(ビューポート変換) 図形の場合表裏を考慮しなくてもいいのですが、目盛(数値・文字)の場合上下を反転させると文字が裏返しになってしまうので、あらかじめ反転した変換をして目盛を書いておく必要があります。
また、目盛を斜めに表示するために、斜めに回転させますが、その回転の中心が原点ではなく、目盛のある点に対して回転させる必要があります。
陰影処理 †
陰影処理はピラミッドの回転で紹介した各ポリゴンの重心を計算し、その重心のy軸方向の値によりソートする方法を使用します。
裏面処理 †
各ポリゴンの法線ベクトルを計算し、法線ベクトル値がマイナスの場合、裏面処理(色を暗くする)をします。
等高線グラフ †
等高線グラフのサンプルです。
PCの場合viewBox内でマウスでクリックした状態で動かして(ドラッグして)等高線グラフを動かして下さい。
スマホの場合viewBox内に指をタッチした状態で動かして(スワイプして)等高線グラフを動かして下さい。
スマホ対応のJavascriptは"スマホ"を参照して下さい。
このグラフは以下のデータを元に作成しています。各データは(x,y,z)の値です。
(0,0,16) (100,0,12) (200,0,9) (300,0,20) (0,100,19) (100,100,44) (200,100,4) (300,100,17) (0,200,19) (100,200,13) (200,200,8) (300,200,16) (0,300,24) (100,300,17) (200,300,16) (300,300,29)