[Study]多面体

umhr_polyhedron以前Matrix3Dの勉強用に作ったもの。4,6,8,12,14,20,30面体にクリックするたびに変わる。
隠面消去とフラットシェーディングに対応。マウスの位置が光源。

多面体座標はこちらを参考にした。→http://blog.livedoor.jp/dankogai/archives/50855972.html

Get Adobe Flash player

http://wonderfl.kayac.com/code/fcebaf728cc38ab746a993ab8ee53e85c0d90a7d

[code lang=”actionscript3″]
/*
多面体の座標はここを参考にした。
http://blog.livedoor.jp/dankogai/archives/50855972.html

4,6,8,12,14,20,30面体がクリックで変わる。
隠面消去とフラットシェーディングに対応している。マウスの位置が光源
*/
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Graphics;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.PerspectiveProjection;
import flash.events.Event;
import flash.events.MouseEvent;
import net.hires.debug.Stats;
[SWF(backgroundColor="0x000000")]
public class Matrix3DTransformsExample extends Sprite {
private var _sp:Sprite=new Sprite;
private var vectors_array:Array;
private var polyInt:int;
private var scale:Number;
public function Matrix3DTransformsExample():void {
var pp:PerspectiveProjection=this.transform.perspectiveProjection;
pp.projectionCenter=new Point(stage.stageWidth/4,stage.stageHeight/4);
this.transform.perspectiveProjection=pp;
_sp.z=_sp.z;
_sp.x=stage.stageWidth/4;
_sp.y=stage.stageHeight/4;
_sp.buttonMode = true;
addChild(_sp);
//polyInt = Math.floor(Math.random()*5);
onClick();
addEventListener(Event.ENTER_FRAME,_fn);
addEventListener(MouseEvent.CLICK,onClick);
addChild(new Stats());
}
private function onClick(e:MouseEvent = null):void{
var _poly:Array = new Array(32,4,6,8,12,14,20);
var model:ModelClass = new ModelClass();
vectors_array = model.getPolyhedron(_poly[polyInt]);
polyInt = (polyInt+1)%7;
scale = Math.sqrt(vectors_array[0][0]*vectors_array[0][0]+vectors_array[0][1]*vectors_array[0][1]+vectors_array[0][2]*vectors_array[0][2]);

}

private var _num:Number=0;
private function _fn(e:Event=null):void {
_num+=0.01;
_sp.graphics.clear();
var vv:Vector.<Vector3D>=new Vector.<Vector3D> ;
vv[0]=new Vector3D(0,0,0);//平行移動、
vv[1]=new Vector3D(_num/2,_num,0);//回転、
vv[2]=new Vector3D(180/scale,180/scale,180/scale);//拡大 / 縮小
var matrix1:Matrix3D=new Matrix3D ;
matrix1.recompose(vv);

var vout_array:Array = new Array();
for (var i:int=0; i<vectors_array.length; i++) {
vout_array[i] = new Vector.<Number>();
matrix1.transformVectors(vectors_array[i],vout_array[i]);
}
render(vout_array);
}

private function render(_pozz:Array):void{
var _len:int=_pozz.length;

var _z_vector:Array=new Array();
for (var i:int=0; i<_len; i++) {
var i_len:int = _pozz[i].length/3;
_z_vector[i] = 0;
for (var j:int=0; j<i_len; j++) {
_z_vector[i] += _pozz[i][j*3+2];
}
}
_z_vector = _z_vector.sort(Array.NUMERIC|Array.RETURNINDEXEDARRAY|Array.DESCENDING);
for (i=0; i<_len; i++) {
drawLine(_pozz[_z_vector[i]],0xFF*(_z_vector[i]/_len));
}
}
private function drawLine(poz:Vector.<Number>,_color:int):void{
//隠面消去
var _vec:Vector3D = new Vector3D(poz[0]-poz[3],poz[1]-poz[4],poz[2]-poz[5]).crossProduct(new Vector3D(poz[0]-poz[6],poz[1]-poz[7],poz[2]-poz[8]));
if(_vec.z > 0 ){
return;
}

//光源、フラットシェーディング
var _mouseX:Number = mouseX-stage.stageWidth/2;
var _mouseY:Number = mouseY-stage.stageHeight/2;
_mouseX = Math.abs(_mouseX)>300?300*_mouseX/Math.abs(_mouseX):_mouseX;
_mouseY = Math.abs(_mouseY)>300?300*_mouseY/Math.abs(_mouseY):_mouseY;
var _ang:Number = Vector3D.angleBetween(_vec,new Vector3D(_mouseX,_mouseY,-400));
//_sp.graphics.lineStyle(0,0xFF0000);
_sp.graphics.beginFill (0xFF*(1-_ang/2), 1);
var _len:int=poz.length;
var ps:Point=new Point(0,0);
ps=_sp.local3DToGlobal(new Vector3D(poz[_len-3],poz[_len-2],poz[_len-1]));
_sp.graphics.moveTo(ps.x,ps.y);
for (var i:int=0; i<_len/3; i++) {
ps=_sp.local3DToGlobal(new Vector3D(poz[i*3],poz[i*3+1],poz[i*3+2]));
_sp.graphics.lineTo(ps.x,ps.y);
}
_sp.graphics.endFill();
}
}
}

import flash.display.Sprite;
class ModelClass extends Sprite {
public function getPolyhedron(_poly:int):Array{
if(_poly == 4){
return Tetrahedron();
}else if(_poly == 6){
return Cube();
}else if(_poly == 8){
return Octahedron();
}else if(_poly == 12){
return Dodecahedron();
}else if(_poly == 14){
return Cuboctahedron();
}else if(_poly == 20){
return Icosahedron();
}else if(_poly == 32){
return Icosidodecahedron();
}
return new Array();
}
//正四面体( 1, 1, 1), ( 1, -1, -1), ( -1, 1, -1), ( -1, -1, 1)
private function Tetrahedron():Array{
var _array:Array = new Array();
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([1,1,1]);
_b = Vector.<Number>([-1,-1,1]);
_c = Vector.<Number>([-1,1,-1]);
_d = Vector.<Number>([1,-1,-1]);
_array.push(_a.concat(_b,_c));
_array.push(_a.concat(_d,_b));
_array.push(_a.concat(_c,_d));
_array.push(_b.concat(_d,_c));
return _array;
}
//正六面体(±1,±1,±1)
private function Cube():Array{
var _array:Array = new Array();
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
var _g:Vector.<Number> = new Vector.<Number>(3,true);
var _h:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([1,1,-1]);
_b = Vector.<Number>([-1,1,-1]);
_c = Vector.<Number>([-1,-1,-1]);
_d = Vector.<Number>([1,-1,-1]);
_e = Vector.<Number>([1,1,1]);
_f = Vector.<Number>([-1,1,1]);
_g = Vector.<Number>([-1,-1,1]);
_h = Vector.<Number>([1,-1,1]);
_array.push(_a.concat(_b,_c,_d));
_array.push(_a.concat(_e,_f,_b));
_array.push(_a.concat(_d,_h,_e));
_array.push(_e.concat(_h,_g,_f));
_array.push(_b.concat(_f,_g,_c));
_array.push(_c.concat(_g,_h,_d));
return _array;
}
//正八面体(±1, 0, 0), ( 0,±1, 0), ( 0, 0,±1)
private function Octahedron():Array{
var _array:Array = new Array();
var phiL:Number = (Math.sqrt(5) + 1)/2;
var phiS:Number = phiL-1;
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([1,0,0]);
_b = Vector.<Number>([-1,0,0]);
_c = Vector.<Number>([0,1,0]);
_d = Vector.<Number>([0,-1,0]);
_e = Vector.<Number>([0,0,1]);
_f = Vector.<Number>([0,0,-1]);
_array.push(_a.concat(_e,_c));
_array.push(_a.concat(_f,_d));
_array.push(_b.concat(_e,_d));
_array.push(_b.concat(_f,_c));
_array.push(_a.concat(_d,_e));
_array.push(_a.concat(_c,_f));
_array.push(_b.concat(_c,_e));
_array.push(_b.concat(_d,_f));
return _array;
}
//正十二面体( 0,±φ,±Φ), (±Φ, 0,±φ), (±φ,±Φ, 0), (±1,±1,±1)
private function Dodecahedron():Array{
var _array:Array = new Array();
var phiL:Number = (Math.sqrt(5) + 1)/2;
var phiS:Number = phiL-1;
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
var _g:Vector.<Number> = new Vector.<Number>(3,true);
var _h:Vector.<Number> = new Vector.<Number>(3,true);
var _i:Vector.<Number> = new Vector.<Number>(3,true);
var _j:Vector.<Number> = new Vector.<Number>(3,true);
var _k:Vector.<Number> = new Vector.<Number>(3,true);
var _l:Vector.<Number> = new Vector.<Number>(3,true);
var _m:Vector.<Number> = new Vector.<Number>(3,true);
var _n:Vector.<Number> = new Vector.<Number>(3,true);
var _o:Vector.<Number> = new Vector.<Number>(3,true);
var _p:Vector.<Number> = new Vector.<Number>(3,true);
var _q:Vector.<Number> = new Vector.<Number>(3,true);
var _r:Vector.<Number> = new Vector.<Number>(3,true);
var _s:Vector.<Number> = new Vector.<Number>(3,true);
var _t:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([0,phiS,phiL]);
_b = Vector.<Number>([0,-phiS,phiL]);
_c = Vector.<Number>([0,-phiS,-phiL]);
_d = Vector.<Number>([0,phiS,-phiL]);
_e = Vector.<Number>([phiL,0,phiS]);
_f = Vector.<Number>([-phiL,0,phiS]);
_g = Vector.<Number>([-phiL,0,-phiS]);
_h = Vector.<Number>([phiL,0,-phiS]);
_i = Vector.<Number>([phiS,phiL,0]);
_j = Vector.<Number>([-phiS,phiL,0]);
_k = Vector.<Number>([-phiS,-phiL,0]);
_l = Vector.<Number>([phiS,-phiL,0]);
_m = Vector.<Number>([1,1,1]);
_n = Vector.<Number>([-1,1,1]);
_o = Vector.<Number>([-1,-1,1]);
_p = Vector.<Number>([1,-1,1]);
_q = Vector.<Number>([1,1,-1]);
_r = Vector.<Number>([-1,1,-1]);
_s = Vector.<Number>([-1,-1,-1]);
_t = Vector.<Number>([1,-1,-1]);
_array.push(_c.concat(_d,_r,_g,_s));
_array.push(_c.concat(_t,_h,_q,_d));
_array.push(_a.concat(_m,_e,_p,_b));
_array.push(_a.concat(_b,_o,_f,_n));
_array.push(_a.concat(_n,_j,_i,_m));
_array.push(_b.concat(_p,_l,_k,_o));
_array.push(_c.concat(_s,_k,_l,_t));
_array.push(_d.concat(_q,_i,_j,_r));
_array.push(_e.concat(_m,_i,_q,_h));
_array.push(_e.concat(_h,_t,_l,_p));
_array.push(_f.concat(_o,_k,_s,_g));
_array.push(_f.concat(_g,_r,_j,_n));
return _array;
}
//立方八面体( 0,±1,±1), (±1, 0,±1), (±1,±1, 0)、14面体
private function Cuboctahedron():Array{
var _array:Array = new Array();
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
var _g:Vector.<Number> = new Vector.<Number>(3,true);
var _h:Vector.<Number> = new Vector.<Number>(3,true);
var _i:Vector.<Number> = new Vector.<Number>(3,true);
var _j:Vector.<Number> = new Vector.<Number>(3,true);
var _k:Vector.<Number> = new Vector.<Number>(3,true);
var _l:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([0,1,1]);
_b = Vector.<Number>([0,-1,1]);
_c = Vector.<Number>([0,-1,-1]);
_d = Vector.<Number>([0,1,-1]);
_e = Vector.<Number>([1,0,1]);
_f = Vector.<Number>([-1,0,1]);
_g = Vector.<Number>([-1,0,-1]);
_h = Vector.<Number>([1,0,-1]);
_i = Vector.<Number>([1,1,0]);
_j = Vector.<Number>([-1,1,0]);
_k = Vector.<Number>([-1,-1,0]);
_l = Vector.<Number>([1,-1,0]);

_array.push(_a.concat(_e,_b,_f));
_array.push(_d.concat(_g,_c,_h));
_array.push(_i.concat(_h,_l,_e));
_array.push(_j.concat(_f,_k,_g));
_array.push(_a.concat(_j,_d,_i));
_array.push(_b.concat(_l,_c,_k));
_array.push(_a.concat(_f,_j));
_array.push(_a.concat(_i,_e));
_array.push(_d.concat(_h,_i));
_array.push(_d.concat(_j,_g));
_array.push(_b.concat(_k,_f));
_array.push(_b.concat(_e,_l));
_array.push(_c.concat(_l,_h));
_array.push(_c.concat(_g,_k));
return _array;
}
//正二十面体( 0,±Φ,±1), (±1, 0,±Φ), (±Φ,±1, 0)
private function Icosahedron():Array{
var _array:Array = new Array();
var phiL:Number = (Math.sqrt(5) + 1)/2;
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
var _g:Vector.<Number> = new Vector.<Number>(3,true);
var _h:Vector.<Number> = new Vector.<Number>(3,true);
var _i:Vector.<Number> = new Vector.<Number>(3,true);
var _j:Vector.<Number> = new Vector.<Number>(3,true);
var _k:Vector.<Number> = new Vector.<Number>(3,true);
var _l:Vector.<Number> = new Vector.<Number>(3,true);
_a = Vector.<Number>([0,phiL,1]);
_b = Vector.<Number>([0,-phiL,1]);
_c = Vector.<Number>([0,-phiL,-1]);
_d = Vector.<Number>([0,phiL,-1]);

_e = Vector.<Number>([1,0,phiL]);
_f = Vector.<Number>([1,0,-phiL]);
_g = Vector.<Number>([-1,0,-phiL]);
_h = Vector.<Number>([-1,0,phiL]);

_i = Vector.<Number>([phiL,1,0]);
_j = Vector.<Number>([-phiL,1,0]);
_k = Vector.<Number>([-phiL,-1,0]);
_l = Vector.<Number>([phiL,-1,0]);
_array.push(_a.concat(_d,_i));
_array.push(_a.concat(_j,_d));
_array.push(_c.concat(_k,_b));
_array.push(_c.concat(_b,_l));
_array.push(_e.concat(_h,_a));
_array.push(_e.concat(_b,_h));
_array.push(_g.concat(_c,_f));
_array.push(_g.concat(_f,_d));
_array.push(_i.concat(_l,_e));
_array.push(_i.concat(_f,_l));
_array.push(_k.concat(_g,_j));
_array.push(_k.concat(_j,_h));
_array.push(_a.concat(_i,_e));
_array.push(_c.concat(_g,_k));
_array.push(_b.concat(_e,_l));
_array.push(_f.concat(_i,_d));
_array.push(_j.concat(_a,_h));
_array.push(_b.concat(_k,_h));
_array.push(_f.concat(_c,_l));
_array.push(_j.concat(_g,_d));
return _array;
}
//二十・十二面体(±2, 0, 0), ( 0,±2, 0), ( 0, 0,±2), (±Φ,±φ,±1), (±1,±Φ,±φ), (±φ,±1,±Φ)、32面体
private function Icosidodecahedron():Array{
var _array:Array = new Array();
var phiL:Number = (Math.sqrt(5) + 1)/2;
var phiS:Number = phiL-1;
var _a0:Vector.<Number> = new Vector.<Number>(3,true);
var _a1:Vector.<Number> = new Vector.<Number>(3,true);
var _a2:Vector.<Number> = new Vector.<Number>(3,true);
var _a3:Vector.<Number> = new Vector.<Number>(3,true);
var _a4:Vector.<Number> = new Vector.<Number>(3,true);
var _a5:Vector.<Number> = new Vector.<Number>(3,true);
var _a:Vector.<Number> = new Vector.<Number>(3,true);
var _b:Vector.<Number> = new Vector.<Number>(3,true);
var _c:Vector.<Number> = new Vector.<Number>(3,true);
var _d:Vector.<Number> = new Vector.<Number>(3,true);
var _e:Vector.<Number> = new Vector.<Number>(3,true);
var _f:Vector.<Number> = new Vector.<Number>(3,true);
var _g:Vector.<Number> = new Vector.<Number>(3,true);
var _h:Vector.<Number> = new Vector.<Number>(3,true);
var _i:Vector.<Number> = new Vector.<Number>(3,true);
var _j:Vector.<Number> = new Vector.<Number>(3,true);
var _k:Vector.<Number> = new Vector.<Number>(3,true);
var _l:Vector.<Number> = new Vector.<Number>(3,true);
var _m:Vector.<Number> = new Vector.<Number>(3,true);
var _n:Vector.<Number> = new Vector.<Number>(3,true);
var _o:Vector.<Number> = new Vector.<Number>(3,true);
var _p:Vector.<Number> = new Vector.<Number>(3,true);
var _q:Vector.<Number> = new Vector.<Number>(3,true);
var _r:Vector.<Number> = new Vector.<Number>(3,true);
var _s:Vector.<Number> = new Vector.<Number>(3,true);
var _t:Vector.<Number> = new Vector.<Number>(3,true);
var _u:Vector.<Number> = new Vector.<Number>(3,true);
var _v:Vector.<Number> = new Vector.<Number>(3,true);
var _w:Vector.<Number> = new Vector.<Number>(3,true);
var _x:Vector.<Number> = new Vector.<Number>(3,true);
_a0 = Vector.<Number>([2,0,0]);
_a1 = Vector.<Number>([-2,0,0]);
_a2 = Vector.<Number>([0,2,0]);
_a3 = Vector.<Number>([0,-2,0]);
_a4 = Vector.<Number>([0,0,2]);
_a5 = Vector.<Number>([0,0,-2]);

_a = Vector.<Number>([phiL,phiS,1]);
_b = Vector.<Number>([-phiL,phiS,1]);
_c = Vector.<Number>([-phiL,-phiS,1]);
_d = Vector.<Number>([phiL,-phiS,1]);
_e = Vector.<Number>([phiL,phiS,-1]);
_f = Vector.<Number>([-phiL,phiS,-1]);
_g = Vector.<Number>([-phiL,-phiS,-1]);
_h = Vector.<Number>([phiL,-phiS,-1]);

_i = Vector.<Number>([1,phiL,phiS]);
_j = Vector.<Number>([1,-phiL,phiS]);
_k = Vector.<Number>([1,-phiL,-phiS]);
_l = Vector.<Number>([1,phiL,-phiS]);
_m = Vector.<Number>([-1,phiL,phiS]);
_n = Vector.<Number>([-1,-phiL,phiS]);
_o = Vector.<Number>([-1,-phiL,-phiS]);
_p = Vector.<Number>([-1,phiL,-phiS]);

_q = Vector.<Number>([phiS,1,phiL]);
_r = Vector.<Number>([-phiS,1,phiL]);
_s = Vector.<Number>([-phiS,1,-phiL]);
_t = Vector.<Number>([phiS,1,-phiL]);
_u = Vector.<Number>([phiS,-1,phiL]);
_v = Vector.<Number>([-phiS,-1,phiL]);
_w = Vector.<Number>([-phiS,-1,-phiL]);
_x = Vector.<Number>([phiS,-1,-phiL]);

_array.push(_a0.concat(_d,_a));
_array.push(_a0.concat(_e,_h));
_array.push(_a1.concat(_b,_c));
_array.push(_a1.concat(_g,_f));
_array.push(_a2.concat(_l,_i));
_array.push(_a2.concat(_m,_p));
_array.push(_a3.concat(_o,_n));
_array.push(_a3.concat(_j,_k));
_array.push(_a4.concat(_u,_v));
_array.push(_a4.concat(_r,_q));
_array.push(_a5.concat(_t,_s));
_array.push(_a5.concat(_w,_x));
_array.push(_p.concat(_f,_s));
_array.push(_m.concat(_r,_b));

_array.push(_n.concat(_c,_v));
_array.push(_o.concat(_w,_g));
_array.push(_l.concat(_t,_e));
_array.push(_q.concat(_i,_a));
_array.push(_x.concat(_k,_h));
_array.push(_j.concat(_u,_d));

_array.push(_a0.concat(_a,_i,_l,_e));
_array.push(_a0.concat(_h,_k,_j,_d));
_array.push(_a1.concat(_f,_p,_m,_b));
_array.push(_a1.concat(_c,_n,_o,_g));
_array.push(_a2.concat(_i,_q,_r,_m));
_array.push(_a2.concat(_p,_s,_t,_l));
_array.push(_a3.concat(_n,_v,_u,_j));
_array.push(_a3.concat(_k,_x,_w,_o));
_array.push(_a4.concat(_v,_c,_b,_r));
_array.push(_a4.concat(_q,_a,_d,_u));
_array.push(_a5.concat(_s,_f,_g,_w));
_array.push(_a5.concat(_x,_h,_e,_t));
return _array;
}
}
[/code]

さらに多面体を増やす場合には以下が参考になりそう。
正多面体、準正多面体、ザルガラー多面体、mxico
http://people.freebsd.org/~maho/mxico/Tamentai.html

配布物(まとめ)
polyhedron.tar.bz2
正多面体、準正多面体、ザルカラーの多面体のすべての頂点座標データ、およびその画像(pbm形式)。 さらに正10角形までの、正多角柱(prism)、正多角反柱(antiprism)も入っています。

 
多面体データ
http://mitani.cs.tsukuba.ac.jp/polyhedron/index.html

多面体画像一覧
http://mitani.cs.tsukuba.ac.jp/polyhedron/image_list.html