昨天已經將球上一點參數化了,就是
x = R * sin(theta) * cos(alpha)
y = R * sin (-pi/2 + theta)
z = R * sin(theta) * sin(alpha)
alpha = 0~2pi, theta=0~pi
今天就來寫一個球的javascript類別,那我們要輸入哪些參數呢?
由以上的方程式知道第一個當然是球的半徑,第二級第三是分別是經度跟緯度,但因為我們只能輸入離散資料,
所以我們要決定的是 alpha與theta要隔多少取樣一次!
所以先完成建構式
function Sphere(radius,latitudinalNum,longitudinalNum)
{
"use strict";
this.radius = radius;
this.latitudinalNum = latitudinalNum;
this.longitudinalNum = longitudinalNum;
this.vertexPosArray = [];
this.vertexNormalArray = [];
this.vertexIndicesArray = [];
}
參數有半徑,緯度取樣數,與精度取樣數,
然後目前這個sphere要產生vertex的位置陣列,法向量陣列,以及組成三角形的索引陣列。
接著我們寫一個建立這些點資訊函式
Sphere.prototype.buildVertex = function(){
var latPace = 1.0 / (this.latitudinalNum-1);
var longPace = 1.0 / (this.longitudinalNum-1);
// pos & normal
for(var i=0;i<this.latitudinalNum;i++){
for(var j=0;j<this.longitudinalNum;j++){
var x = Math.cos(2*Math.PI*j*longPace) * Math.sin(Math.PI*i*latPace);
var y = Math.sin(-Math.PI/2 + Math.PI*i*latPace);
var z = Math.sin(2*Math.PI*j*longPace) * Math.sin(Math.PI*i*latPace);
this.vertexPosArray.push(x*this.radius);
this.vertexPosArray.push(y*this.radius);
this.vertexPosArray.push(z*this.radius);
this.vertexNormalArray.push(x);
this.vertexNormalArray.push(y);
this.vertexNormalArray.push(z);
}
}
// indices
for(var i=0;i<this.latitudinalNum-1;i++){
for(var j=0;j<this.longitudinalNum-1;j++){
this.vertexIndicesArray.push(i*this.longitudinalNum+j);
this.vertexIndicesArray.push(i*this.longitudinalNum+ (j+1) );
this.vertexIndicesArray.push( (i+1) *this.longitudinalNum+j);
this.vertexIndicesArray.push(i*this.longitudinalNum+ (j+1) );
this.vertexIndicesArray.push( (i+1) *this.longitudinalNum+ (j+1) );
this.vertexIndicesArray.push( (i+1) *this.longitudinalNum+j);
}
}
}
首先我們根據取樣數量,取得精度與緯度間隔,
然後再根據方程式算出質點的位置坐標與法向量(法向量 *球半徑就是位置坐標!),
最後在建立索引陣列,索引陣列基本上是經緯度交叉出來的四個點,所組成的兩個三角形頂點的索引陣列。
只能利用下班時間寫文章果然不容易哈哈!今天先到這邊。