思い立ったらやってみていた。
角度は制限してないので、めり込んでいくスタイル。
マウスでドラッグすると視点を動かせます。
See the Pen polyhedral net - three js by kob58im (@kob58im) on CodePen.
はまったこと
-
DoubleSide
を指定しないと裏面が描画されない。 - クォータニオンとマトリクスは併用できないっぽい。(結果的にマトリクスに集約した。)
-
THREE.Shape
のlineTo
での点の登録順序と、ShapeGeometry
のgeometry
の頂点vertex
の順序が逆順になる??
説明兼備忘録
(回転させる前の)展開図の座標を作る
面と辺を選んで、その辺に隣接する正多角形を追加していく。
const polyGenF = [-1,0,0,1,3,3,3,3,2,2,2,2]; // refering Face index
const polyGenI = [-1,0,2,1,0,1,2,3,0,1,2,3]; // refering edge Index
const polyGenN = [ 5,5,5,5,5,5,5,5,5,5,5,5]; // N-polygon
const edgeLen = 150;
const N = polyGenF.length;
中略
iniFaces = [newFaceTouchEdgeByP(new Point(0, 0), new Point(0, edgeLen), polyGenN[0])];
for ( let i=1; i<N; i++ ) {
iniFaces.push(newFaceTouchEdgeByI(iniFaces, polyGenF[i], polyGenI[i], polyGenN[i]));
}
中略
// 指定した多角形(initialFacesPoints[faceI])の
// edgeI+1番目の辺に隣接する正polyN角形の座標ポイントを生成して返す。
// 辺の座標の順番はラジアンの方向まわりで合わせる。
function newFaceTouchEdgeByI(facesPoints,faceI,edgeI,polyN) {
const p0 = facesPoints[faceI][edgeI];
const p1 = facesPoints[faceI][(edgeI+1)%(facesPoints[faceI].length)];
return newFaceTouchEdgeByP(p0,p1,polyN);
}
function newFaceTouchEdgeByP(p0,p1,polyN) {
//const edgeLen = calcDistance(p0,p1);
let theta = calcAngle(p0,p1) - (Math.PI*(1-2/polyN));
let x = p0.x;
let y = p0.y;
let a = [new Point(x,y)];
for ( let i=1; i<polyN; i++ ) {
x += edgeLen*Math.cos(theta);
y += edgeLen*Math.sin(theta);
a.push(new Point(x, y));
theta += 2*Math.PI/polyN;
}
return a;
}
面(複数)を選んで辺を軸として回転させる
配列polyGenF
等のindex 0の面をルート(親)ノードとして、直下の子ノードにあたる隣接面を選択し、各ノードの親との共有辺を回転軸として、つながっている面(=子孫となるノード)をすべて一律回転させる。これを再帰的にやっている。(語彙力・・)