それでは,
第2に,
そして第3に,
// フレームアクションに追加
var backTexture:BitmapData = new Image2(); // 追加
function xRotate(eventObject:Event):void {
var nRotationY:Number = mySprite.mouseX * nDeceleration;
var vertices2D:Vector.<Number> = new Vector.<Number>();
xTransform(vertices2D, nRotationY);
var bFront:Boolean = xIsFront(faceVector3D, worldMatrix3D);
// trace(bFront); // 確認用
// xDraw(vertices2D);
xDraw(vertices2D, bFront);
}
// function xDraw(vertices2D:Vector.<Number>):void {
function xDraw(vertices2D:Vector.<Number>, bFront:Boolean):void {
var texture:BitmapData = bFront ? myTexture : backTexture; // 追加
myGraphics.clear();
// myGraphics.beginBitmapFill(myTexture);
myGraphics.beginBitmapFill(texture);
myGraphics.drawTriangles(vertices2D, indices, uvtData);
myGraphics.endFill();
}
修正し終えたフレームアクション全体を,
スクリプト1 水平に回す立方体の裏表を異なるテクスチャでマッピング
// フレームアクション
var nUnit:Number = 100 / 2;
var mySprite:Sprite = new Sprite();
var myTexture:BitmapData = new Image();
var backTexture:BitmapData = new Image2();
var viewVector3D:Vector3D = Vector3D.Z_AXIS;
var faceVector3D:Vector3D = new Vector3D(0, 0, -1);
var vertices:Vector.<Number> = new Vector.<Number>();
var indices:Vector.<int> = new Vector.<int>();
var uvtData:Vector.<Number> = new Vector.<Number>();
var nDeceleration:Number = 0.3;
var myGraphics:Graphics = mySprite.graphics;
var myPerspective:PerspectiveProjection = transform.perspectiveProjection;
var worldMatrix3D:Matrix3D = new Matrix3D();
var viewMatrix3D:Matrix3D = myPerspective.toMatrix3D();
viewMatrix3D.prependTranslation(0, 0, myPerspective.focalLength);
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
vertices.push(-nUnit, -nUnit, 0);
vertices.push(nUnit, -nUnit, 0);
vertices.push(nUnit, nUnit, 0);
vertices.push(-nUnit, nUnit, 0);
indices.push(0, 1, 3);
indices.push(1, 2, 3);
uvtData.push(0, 0, 0);
uvtData.push(1, 0, 0);
uvtData.push(1, 1, 0);
uvtData.push(0, 1, 0);
addChild(mySprite);
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
var nRotationY:Number = mySprite.mouseX * nDeceleration;
var vertices2D:Vector.<Number> = new Vector.<Number>();
xTransform(vertices2D, nRotationY);
var bFront:Boolean = xIsFront(faceVector3D, worldMatrix3D);
xDraw(vertices2D, bFront);
}
function xTransform(vertices2D:Vector.<Number>, myRotation:Number):void {
worldMatrix3D.prependRotation(myRotation, Vector3D.Y_AXIS);
var myMatrix3D:Matrix3D = worldMatrix3D.clone();
myMatrix3D.append(viewMatrix3D);
Utils3D.projectVectors(myMatrix3D, vertices, vertices2D, uvtData);
}
function xDraw(vertices2D:Vector.<Number>, bFront:Boolean):void {
var texture:BitmapData = bFront ? myTexture : backTexture;
myGraphics.clear();
myGraphics.beginBitmapFill(texture);
myGraphics.drawTriangles(vertices2D, indices, uvtData);
myGraphics.endFill();
}
function xIsFront(myVector3D:Vector3D, myMatrix3D:Matrix3D):Boolean {
var directionVector3D:Vector3D = myMatrix3D.transformVector(myVector3D);
var bFront:Boolean = (viewVector3D.dotProduct(directionVector3D) < 0);
return bFront;
}
ベクトルの内積を数学的に理解する
ベクトルの内積について,
ベクトルAとBの内積は,
A・
B = |A||B|cosθ A||B| > 0 (|A|≠0,
|B|≠0とする) A・
B = axbx + ayby A・
B = axbx + ayby + azbz - ※1)
- ふたつのベクトルの絶対値およびcosによる内積の定義と,
座標による計算の結果は等しくなる。しかし, それは自明ではなく, 余弦定理により証明しなければならない。興味のある読者は 「Vector3D. dotProduct()メソッド 」の 「数学解説」 をお読みいただきたい。 - スクリプト1のサンプルファイル
(CS5形式/約61KB)
ベクトルAとBの始点を結んだとき,
ベクトルAとBの絶対値は,
つまり,
内積は,
3次元空間のベクトルA
次回は,
今回解説した次のサンプルファイルがダウンロードできます。