forked from: C60分子構造の表示
/**
* Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jxLN
*/
// forked from hi.kurosawa's C60分子構造の表示
//================================================
//分子構造の表示
// 登録時分子画像の透明部分がなくなったため四角で表示しています
// 本当は丸で表示しいます。
// こちらで確認できます:http://programmingatelier.net/
//
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.ColorTransform;
import org.papervision3d.materials.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.objects.*;
import org.papervision3d.lights.*;
import org.papervision3d.materials.shadematerials.*;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.special.CompositeMaterial;
import org.papervision3d.view.*;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.typography.fonts.HelveticaMedium;
import org.papervision3d.materials.special.Letter3DMaterial;
import org.papervision3d.typography.Text3D;
import org.papervision3d.typography.fonts.HelveticaBold;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.core.math.Number3D;
public class Main extends BasicView
{
//使用画像定義(黒白の原子のイメージ)
//[Embed(source='img/Atom.png')]
// private var imgAtom:Class;
private var bmAtom:Bitmap;
private var loader:Loader;
//private static var filePath:String = "http://localhost/flex4/MoleculeAs/bin/Atom.png";
private static var filePath:String = "http://assets.wonderfl.net/images/related_images/a/ac/acdd/acdd66866c7c3e611c425730c5d876a11f1d95a9m";
//3D形状の配置領域
//private var bv:BasicView;
private var rootNode:DisplayObject3D;
//データのあるパス
private var strDatUrl:String;
//表示Atom配列、カメラ移動時の向きの調整用
private var arrObj:Array;
//PDB読み込み原子と結合線データ
private var arrAtom:Array;
//Typ:ATOM/HETATM,nam:名称,id:NO,x,y,z:原子の座標値*100
private var arrConect:Array;
//StrCon:開始点側原子ID, EndCon:終点側原子ID
private var kakudo0:Number;
private var kakudo1:Number;
private var kakudo2:Number;
public function Main():void {
arrObj = new Array();
arrAtom = new Array(
{Typ:"ATOM",id: 1,nam:"C1 ",x:-118.1,y:-521.9,z: 052.3},
{Typ:"ATOM",id: 2,nam:"C2 ",x:-152.7,y:-421.9,z: 144.9},
{Typ:"ATOM",id: 3,nam:"C3 ",x:-292.6,y:-422.5,z: 159.3},
{Typ:"ATOM",id: 4,nam:"C4 ",x:-250.7,y:-625.2,z:-126.1},
{Typ:"ATOM",id: 5,nam:"C5 ",x:-145.7,y:-603.5,z:-217.1},
{Typ:"ATOM",id: 6,nam:"C6 ",x:-025.7,y:-540.6,z:-173.6},
{Typ:"ATOM",id: 7,nam:"C7 ",x:-012.0,y:-499.9,z:-039.8},
{Typ:"ATOM",id: 8,nam:"C8 ",x:-081.4,y:-298.9,z: 146.6},
{Typ:"ATOM",id: 9,nam:"C9 ",x: 023.6,y:-277.1,z: 055.6},
{Typ:"ATOM",id:10,nam:"C10",x: 058.5,y:-378.1,z:-038.1},
{Typ:"ATOM",id:11,nam:"C11",x:-362.8,y:-299.8,z: 175.4},
{Typ:"ATOM",id:12,nam:"C12",x:-292.4,y:-178.1,z: 177.0},
{Typ:"ATOM",id:13,nam:"C13",x:-372.1,y:-604.3,z:-193.9},
{Typ:"ATOM",id:14,nam:"C14",x:-536.5,y:-380.1,z: 022.8},
{Typ:"ATOM",id:15,nam:"C15",x:-484.2,y:-278.8,z: 107.7},
{Typ:"ATOM",id:16,nam:"C16",x:-202.3,y:-569.5,z:-341.3},
{Typ:"ATOM",id:17,nam:"C17",x:-342.3,y:-569.8,z:-327.0},
{Typ:"ATOM",id:18,nam:"C18",x: 088.3,y:-343.6,z:-171.1},
{Typ:"ATOM",id:19,nam:"C19",x: 036.5,y:-444.0,z:-254.8},
{Typ:"ATOM",id:20,nam:"C20",x:-593.4,y:-346.0,z:-101.2},
{Typ:"ATOM",id:21,nam:"C21",x:-558.9,y:-446.1,z:-193.9},
{Typ:"ATOM",id:22,nam:"C22",x:-370.3,y:-082.0,z: 110.2},
{Typ:"ATOM",id:23,nam:"C23",x:-488.8,y:-144.3,z: 067.1},
{Typ:"ATOM",id:24,nam:"C24",x:-021.0,y:-409.3,z:-380.2},
{Typ:"ATOM",id:25,nam:"C25",x:-139.5,y:-471.6,z:-423.2},
{Typ:"ATOM",id:26,nam:"C26",x:-528.6,y:-411.2,z:-328.3},
{Typ:"ATOM",id:27,nam:"C27",x:-421.0,y:-472.6,z:-394.5},
{Typ:"ATOM",id:28,nam:"C28",x:-546.3,y:-109.6,z:-058.2},
{Typ:"ATOM",id:29,nam:"C29",x:-598.1,y:-210.0,z:-142.0},
{Typ:"ATOM",id:30,nam:"C30",x:-167.5,y: 016.2,z: 013.9},
{Typ:"ATOM",id:31,nam:"C31",x:-307.5,y: 015.9,z: 028.2},
{Typ:"ATOM",id:32,nam:"C32",x: 049.1,y:-107.5,z:-119.2},
{Typ:"ATOM",id:33,nam:"C33",x: 083.7,y:-207.6,z:-211.8},
{Typ:"ATOM",id:34,nam:"C34",x:-217.4,y:-375.5,z:-490.1},
{Typ:"ATOM",id:35,nam:"C35",x:-358.9,y:-375.9,z:-475.6},
{Typ:"ATOM",id:36,nam:"C36",x:-028.6,y:-011.4,z:-186.1},
{Typ:"ATOM",id:37,nam:"C37",x:-137.7,y: 050.7,z:-119.2},
{Typ:"ATOM",id:38,nam:"C38",x:-364.2,y: 049.9,z:-096.0},
{Typ:"ATOM",id:39,nam:"C39",x:-484.1,y:-013.1,z:-139.5},
{Typ:"ATOM",id:40,nam:"C40",x:-568.3,y:-175.5,z:-274.9},
{Typ:"ATOM",id:41,nam:"C41",x:-533.3,y:-276.5,z:-368.6},
{Typ:"ATOM",id:42,nam:"C42",x:-497.8,y:-053.7,z:-273.3},
{Typ:"ATOM",id:43,nam:"C43",x:-259.1,y: 071.6,z:-187.0},
{Typ:"ATOM",id:44,nam:"C44",x:-481.2,y:-542.2,z:-126.9},
{Typ:"ATOM",id:45,nam:"C45",x:-467.4,y:-501.6,z: 007.0},
{Typ:"ATOM",id:46,nam:"C46",x:-344.5,y:-522.8,z: 075.6},
{Typ:"ATOM",id:47,nam:"C47",x:-236.7,y:-584.2,z: 009.4},
{Typ:"ATOM",id:48,nam:"C48",x:-150.9,y:-177.7,z: 162.5},
{Typ:"ATOM",id:49,nam:"C49",x:-088.8,y:-081.1,z: 081.4},
{Typ:"ATOM",id:50,nam:"C50",x: 018.9,y:-142.5,z: 015.2},
{Typ:"ATOM",id:51,nam:"C51",x:-428.4,y:-254.7,z:-459.6},
{Typ:"ATOM",id:52,nam:"C52",x:-391.7,y:-031.7,z:-365.4},
{Typ:"ATOM",id:53,nam:"C53",x:-357.1,y:-131.7,z:-458.0},
{Typ:"ATOM",id:54,nam:"C54",x:-147.0,y:-253.8,z:-488.4},
{Typ:"ATOM",id:55,nam:"C55",x:-025.6,y:-274.8,z:-420.7},
{Typ:"ATOM",id:56,nam:"C56",x:-217.2,y:-131.2,z:-472.4},
{Typ:"ATOM",id:57,nam:"C57",x: 026.8,y:-173.5,z:-335.8},
{Typ:"ATOM",id:58,nam:"C58",x:-042.4,y:-052.0,z:-320.1},
{Typ:"ATOM",id:59,nam:"C59",x:-273.1,y: 030.6,z:-322.5},
{Typ:"ATOM",id:60,nam:"C60",x:-165.2,y:-030.8,z:-388.6}
);
arrConect = new Array(
{StrCon:1, EndCon:2},
{StrCon:1, EndCon:7},
{StrCon:1, EndCon:47},
{StrCon:2, EndCon:3},
{StrCon:2, EndCon:8},
{StrCon:3, EndCon:11},
{StrCon:3, EndCon:46},
{StrCon:4, EndCon:5},
{StrCon:4, EndCon:13},
{StrCon:4, EndCon:47},
{StrCon:5, EndCon:6},
{StrCon:5, EndCon:16},
{StrCon:6, EndCon:7},
{StrCon:6, EndCon:19},
{StrCon:7, EndCon:10},
{StrCon:8, EndCon:9},
{StrCon:8, EndCon:48},
{StrCon:9, EndCon:10},
{StrCon:9, EndCon:50},
{StrCon:10, EndCon:18},
{StrCon:11, EndCon:12},
{StrCon:11, EndCon:15},
{StrCon:12, EndCon:22},
{StrCon:12, EndCon:48},
{StrCon:13, EndCon:17},
{StrCon:13, EndCon:44},
{StrCon:14, EndCon:15},
{StrCon:14, EndCon:20},
{StrCon:14, EndCon:45},
{StrCon:15, EndCon:23},
{StrCon:16, EndCon:17},
{StrCon:16, EndCon:25},
{StrCon:17, EndCon:27},
{StrCon:18, EndCon:19},
{StrCon:18, EndCon:33},
{StrCon:19, EndCon:24},
{StrCon:20, EndCon:21},
{StrCon:20, EndCon:29},
{StrCon:21, EndCon:26},
{StrCon:21, EndCon:44},
{StrCon:22, EndCon:23},
{StrCon:22, EndCon:31},
{StrCon:23, EndCon:28},
{StrCon:24, EndCon:25},
{StrCon:24, EndCon:55},
{StrCon:25, EndCon:34},
{StrCon:26, EndCon:27},
{StrCon:26, EndCon:41},
{StrCon:27, EndCon:35},
{StrCon:28, EndCon:29},
{StrCon:28, EndCon:39},
{StrCon:29, EndCon:40},
{StrCon:30, EndCon:31},
{StrCon:30, EndCon:37},
{StrCon:30, EndCon:49},
{StrCon:31, EndCon:38},
{StrCon:32, EndCon:33},
{StrCon:32, EndCon:36},
{StrCon:32, EndCon:50},
{StrCon:33, EndCon:57},
{StrCon:34, EndCon:35},
{StrCon:34, EndCon:54},
{StrCon:35, EndCon:51},
{StrCon:36, EndCon:37},
{StrCon:36, EndCon:58},
{StrCon:37, EndCon:43},
{StrCon:38, EndCon:39},
{StrCon:38, EndCon:43},
{StrCon:39, EndCon:42},
{StrCon:40, EndCon:41},
{StrCon:40, EndCon:42},
{StrCon:41, EndCon:51},
{StrCon:42, EndCon:52},
{StrCon:43, EndCon:59},
{StrCon:44, EndCon:45},
{StrCon:45, EndCon:46},
{StrCon:46, EndCon:47},
{StrCon:48, EndCon:49},
{StrCon:49, EndCon:48},
{StrCon:49, EndCon:50},
{StrCon:51, EndCon:53},
{StrCon:52, EndCon:53},
{StrCon:52, EndCon:59},
{StrCon:53, EndCon:56},
{StrCon:54, EndCon:55},
{StrCon:54, EndCon:56},
{StrCon:55, EndCon:57},
{StrCon:56, EndCon:60},
{StrCon:57, EndCon:58},
{StrCon:58, EndCon:60},
{StrCon:59, EndCon:60}
);
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete, false, 0, true);
loader.load(new URLRequest(filePath), new LoaderContext(true));
}
private function complete(evt:Event):void {
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, complete);
bmAtom = Bitmap(loader.content);
fncDispAtom(-300, -300, 0);
}
//原子結合線表示
//dx,dy,dz:中心座標
private function fncDispAtom(dx:Number, dy:Number, dz:Number):void {
//3D形状の配置領域作成
rootNode = new DisplayObject3D();
this.scene.addChild(rootNode);
rootNode.x = 0;
//原子の表示
for (var k:int = 0; k < arrAtom.length; k++) {
rootNode.addChild(mkAtom(arrAtom[k].nam,
(arrAtom[k].x-dx), (arrAtom[k].y-dy), (arrAtom[k].z-dz), 20, 0x0000ff,0xff00ff));
}
//結合線の表示
for (var l:int = 0; l < arrConect.length; l++) {
var id1:int = getAtomID(arrConect[l].StrCon);
var id2:int = getAtomID(arrConect[l].EndCon);
if (id1 >= 0 && id2 >= 0) {
rootNode.addChild(mkLine(
(arrAtom[id1].x-dx) , (arrAtom[id1].y-dy) , (arrAtom[id1].z-dz) ,
(arrAtom[id2].x - dx) , (arrAtom[id2].y - dy) , (arrAtom[id2].z - dz),
20, 20, 0x888888));
}
}
//onSlChmg();
kakudo0 = 0;
kakudo1 = 0;
kakudo2 = 0;
addEventListener(Event.ENTER_FRAME, onFrame);
}
private function onFrame(e:Event):void
{
kakudo0 += 0.3;
kakudo1++;
if (kakudo1 >= 360) { kakudo1 = 0; }
if (kakudo0 >= 360) { kakudo0 -= 360; }
kakudo2 = Math.sin(kakudo0 * Math.PI / 180) * 80;
onSlChmg();
}
//結合線の両端に付く原子を求める
// iCon:原子のID
// 戻り値:arrAtomの位置(-1:対応する原子なし)
private function getAtomID(iCon:int):int {
for (var i:int; i < arrAtom.length; i++) {
if (iCon == arrAtom[i].id) { return i;}
}
return -1;
}
//原子の表示
// nam:表示する名称
// x,y,z:表示位置
// r:半径
// uiAtomCol:原子の色
// uiNameCol:表示名称の色
// 戻り値:オブジェクト
private function mkAtom(nam:String, x:Number, y:Number, z:Number, r:Number,
uiAtomCol:uint,uiNameCol:uint):DisplayObject3D {
var objNode:DisplayObject3D=new DisplayObject3D();
//原子
var objPlane:Plane;
//var bmAtom:Bitmap = Bitmap(new imgAtom);
var matrAtom:BitmapMaterial = new BitmapMaterial(bmAtom.bitmapData,true);
matrAtom.smooth = true;
matrAtom.oneSide = true;
//matrAtom.doubleSided = true; //裏表示
objPlane = new Plane(matrAtom, r * 2, r * 2, 1, 1);
objNode.addChild(objPlane);
var ir:uint = uiAtomCol / (256 * 256); //カラーをRGBに分解
var ig:uint = (uiAtomCol / (256))-ir*256;
var ib:uint = uiAtomCol % 256;
//イメージの黒色部分を指定カラーに変更
objPlane.material.bitmap.colorTransform(objPlane.material.bitmap.rect,
new ColorTransform(1.0,1.0,1.0,1.0, ir, ig, ib,0));
//名称の表示
var LMaterial:Letter3DMaterial = new Letter3DMaterial(uiNameCol , 1);
//LMaterial.doubleSided = true; //裏表示
var fnt:HelveticaBold = new HelveticaBold();
var word:Text3D = new Text3D(nam, fnt , LMaterial);
word.z = -10.0; //手前に表示
word.x = 10.0+nam.length*10.0;
word.y = 20.0;
word.scale = 0.5;
objNode.addChild(word);
//(原子+名称)の位置
objNode.x = x;
objNode.y = y;
objNode.z = z;
//表示処理用の配列にセット
arrObj.push(objNode);
return objNode;
}
//結合線
// x1,y1,z1,x2,y2,z3:結合線の始終点
// r1,r2:付く原子の半径(半径分表示線分を短くする)
// ic:カラー
private function mkLine(x1:Number, y1:Number, z1:Number,
x2:Number, y2:Number, z2:Number,
r1:Number, r2:Number, ic:uint):Lines3D {
//ラインの単位ベクトルを求める
var dx:Number = x2 - x1;
var dy:Number = y2 - y1;
var dz:Number = z2 - z1;
var dd:Number = Math.sqrt(dx * dx + dy * dy + dz * dz);
if (dd > 0.0) {
dx = dx / dd;
dy = dy / dd;
dz = dz / dd;
}
//線を引く
var lm:LineMaterial = new LineMaterial(ic);
var lines3D:Lines3D = new Lines3D();
var startV:Vertex3D = new Vertex3D(x1+r1*dx, y1+r1*dy, z1+r1*dz);
var endV:Vertex3D = new Vertex3D(x2-r2*dx, y2-r2*dy, z2-r2*dz);
var line:Line3D = new Line3D(lines3D, lm, 5, startV, endV);
lines3D.addLine(line);
return lines3D;
}
//Sliderの値変更:カメラの位置セット、形状表示
private function onSlChmg():void {
//カメラ位置
var kyori:Number = 1000;//原点・カメラの距離
//高さ方向の角度(ラジアン)
var ang1:Number = kakudo2 * Math.PI / 180.0;
//方向(ラジアン)
var ang2:Number = (kakudo1-180) * Math.PI / 180.0;
var x:Number=kyori*Math.cos(ang1)*Math.sin(ang2);
var y:Number=kyori*Math.cos(ang1)*Math.cos(ang2);
var z:Number = kyori*Math.sin(ang1);
this.camera.x = x;
this.camera.z = y;
this.camera.y = z;
//this.camera.zoom=40.0;
//原子(Plenで表示)を正面を向かせる。
for (var i:int = 0; i < arrObj.length; i++) {
//lookAtで原子をカメラに向けると文字等がうまく表示されない
//arrObjAtom[i].lookAt( bv.camera );
//arrObjAtom[i].yaw(180);
arrObj[i].rotationX = kakudo2;
arrObj[i].rotationY = kakudo1;
}
//描画処理
this.renderer.renderScene( this.scene , this.camera , this.viewport );
}
}
}