メイン

2009年06月21日

five3Dメモ

http://d.hatena.ne.jp/nitoyon/20080513/p1

player10が使えない場合、手軽にパースをかけたいと思ったときはfive3Dを使う。

2009年04月06日

3d参考

http://level0.kayac.com/2009/03/3d_engine.php

2009年01月06日

3d

勉強になります
http://yamasv.blog92.fc2.com/blog-entry-142.html

以下転載
--


package{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.*;

import org.papervision3d.core.math.*;

[SWF(width="400", height="400",backgroundColor="0xffffff")]

public class Light3D extends Sprite{
private var m:Matrix3D = new Matrix3D();
private var rm:Matrix3D = new Matrix3D();

private var lastPoint:Point;
private var mouseDown:Boolean = false;

private var objects:Array = [];

public function Light3D(){

var r:Number = 500;
var l:Number = -500;
var t:Number = 500;
var b:Number = -500;
var n:Number = 500;
var f:Number = 1000;
m.n11 = 2*n/(r-l);
m.n13 = (r+l)/(r-l);
m.n22 = 2*n/(t-b);
m.n23 = (t+b)/(t-b);
m.n33 = -(f+n)/(f-n);
m.n34 = -2*n*f/(f-n);
m.n43 = -1;

var triangle:Triangle = new Triangle();
addChild(triangle);
triangle.redraw(m, rm);
triangle.zz = 0;
objects.push(triangle);

var star:Star = new Star();
addChild(star);
star.redraw(m, rm);
star.zz = 50;
objects.push(star);

var rectangle:Rectangle = new Rectangle();
addChild(rectangle);
rectangle.redraw(m, rm);
rectangle.zz = 100;
objects.push(rectangle);

stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:*):void{
mouseDown = true;
lastPoint = new Point(stage.mouseX, stage.mouseY);
});
stage.addEventListener(MouseEvent.MOUSE_UP, function(e:*):void{
mouseDown = false;
lastPoint = new Point(stage.mouseX, stage.mouseY);
});
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}

private function onMouseMove(e:*):void{
if(!mouseDown)
return;

var xx:Number = stage.mouseX - lastPoint.x;
var yy:Number = -stage.mouseY + lastPoint.y;
if(yy == 00) return;

var rotAxis:Number3D = new Number3D();

rotAxis.z = 0;
rotAxis.x = yy;
rotAxis.y = -xx;

// calculate the amount of rotation
var rotAngle:Number = Math.sqrt(xx*xx + yy*yy)/200*Math.PI;
if(rotAngle == 0) return;

rotAxis.normalize();
rm = Matrix3D.multiply(Matrix3D.rotationMatrix(rotAxis.x, rotAxis.y, 0, rotAngle), rm);

lastPoint = new Point(stage.mouseX, stage.mouseY);

for each(var o:Base3D in objects){
o.redraw(m, rm);
}

// 本当はZオーダーを考慮して並べ替える
if(rm.n33 < 0){
setChildIndex(objects[0],2);
setChildIndex(objects[1],1);
setChildIndex(objects[2],0);
}else{
setChildIndex(objects[0],0);
setChildIndex(objects[1],1);
setChildIndex(objects[2],2);
}
}
}
}

internal class Base3D extends Sprite{
public var xx:int ;
public var yy:int ;
public var zz:int ;

public function redraw(m:Matrix3D, rm:Matrix3D):void{
}

protected function convertPoint(p:Number3D, m:Matrix3D, rm:Matrix3D):Point{

// apply camera rotation
Matrix3D.multiplyVector(rm,p);

// convert to 2D point
Matrix3D.multiplyVector(m,p);

return new Point(p.x + 200, 200 - p.y);
}
}

import flash.display.Sprite;
import flash.geom.*;

import org.papervision3d.core.math.*;

internal class Triangle extends Base3D {

public function Triangle() {
}

public override function redraw(m:Matrix3D, rm:Matrix3D):void{
graphics.clear();
graphics.lineStyle(1, 0, 1);
graphics.beginFill(0xff0000);
var p:Point = convertPoint(new Number3D(-30,-30,zz), m, rm);
var p2:Point = convertPoint(new Number3D(30,30,zz), m, rm);
var p3:Point = convertPoint(new Number3D(-30,30,zz), m, rm);

graphics.moveTo(p.x, p.y);
graphics.lineTo(p2.x, p2.y);
graphics.lineTo(p3.x, p3.y);
graphics.endFill();

}
}

internal class Rectangle extends Base3D {

public function Rectangle() {
}

public override function redraw(m:Matrix3D, rm:Matrix3D):void{
graphics.clear();
graphics.lineStyle(1, 0, 1);
graphics.beginFill(0xff00);
var p:Point = convertPoint(new Number3D(0,0,zz), m, rm);
var p2:Point = convertPoint(new Number3D(0,150,zz), m, rm);
var p3:Point = convertPoint(new Number3D(150, 150,zz), m, rm);
var p4:Point = convertPoint(new Number3D(150, 0,zz), m, rm);

graphics.moveTo(p.x, p.y);
graphics.lineTo(p2.x, p2.y);
graphics.lineTo(p3.x, p3.y);
graphics.lineTo(p4.x, p4.y);
graphics.endFill();

}
}

internal class Star extends Base3D{
public function Star(){
}

public override function redraw(m:Matrix3D, rm:Matrix3D):void{
graphics.clear();
graphics.lineStyle(1, 0xff, 0.8);
graphics.beginFill(0xff);
var seq:Array=[2,4,1,3,0];
var p0:Point = convertPoint(new Number3D(100, 200, zz), m, rm);
graphics.moveTo(p0.x, p0.y);
for(var j:int = 0 ; j < 5 ; j++){
var rad:Number = seq[j] * Math.PI * 2 / 5;
var p:Point = convertPoint(new Number3D(-Math.sin(rad)*100+100, Math.cos(rad)*100+100, zz), m, rm);
graphics.lineTo(p.x, p.y);
}
graphics.endFill();

}
}

2008年04月11日

particle

particle、ちっこいつぶつぶを動かすサンプルを見ていると

各つぶ の描画にはsetPixelsとかを使い

各つぶは、displayObjectではなく、単なるデータ(色、位置、大きさ)
しか持たない。

こっちのほうが高速なんだろうな。

2008年02月03日

焦点距離

3dのパースの式
scale = fl / (fl + z)

焦点距離flを小さくすると、スケールが急激に変化=広角気味
焦点距離flを大きくすると、スケールがゆるやかに変化=望遠気味

--

ここでいうflはpapervisionのcamera.focusに相当?

2008年01月27日

3d基礎知識

http://www.ceres.dti.ne.jp/~ykuroda/oyaj/bone/basic3d.html

2007年11月28日

3d #3 座標回転

3dでの座標回転を考えて見ます。

軸は下記のように定義。
x軸:ディスプレイの横方向
y軸:ディスプレイの縦方向
z軸:z軸は奥行きのほうこうです。ディスプレイを突き抜ける方向です。

回転をイメージしてみる。
x軸回転:タイヤを前面から観測
y軸回転:円盤、CDプレイヤーを考えよう
z軸回転:ルーレット盤を上から観測しよう

---

とりあえず3Dの前に、2Dでの回転を考えます。公式は下記です。
(x,y)をangle回転させて(x1,x2)になります。

x1 = cos(angle)*x - sin(angle)*y
y1 = cos(angle)*y + sin(angle)*x

この式はなぜこうなるのか。。合ってるか知らんが考えてみる。
(x1,y1)を極座標で下記のように表す。a0は(x,y)がなす角度。
 abs1 = Math.sqrt(x1*x1+y1*y*1)
 x1 = abs1 * cos( a0 +angle)
 y1 = abs1 * sin( a0 + angle)

これを加法定理で分解。
 x1 =abs1 *( cos(a0)*cos(angle) - sin(a0)*sin(angle) );
 y1 =abs1 *( sin(a0)*cos(angle) + cos(a0)*sin(sngle) );

で、ここでの話は回転だけであって(たぶん)、変換後の絶対値は変わらない。つまり
 abs1=Math.sqrt(x*x+y*y)

であるから
 abs1 * cos(a0) = x
 abs1 * sin(a0) = y

と考えられる。よって、式をきれいに書き直すと
 x1 =x*cos(angle) - y*sin(angle);
 y1 =y*cos(angle) + x*sin(sngle) );

できたー!


3d #2 焦点距離なるものに対する考察

焦点距離とは何なのか、よくわからないので考察をします。本にはカメラの焦点距離とは厳密には違うと書いてありました。それがナニを意図するのか分かりません。。

具体的に見ていったほうがイメージしやすいかもしれないので、焦点距離fl=30,fl=3000としてものを図示しました。
zToScale30.gif
zToScale3000.gif

焦点距離を小さくすると、つまり視点を投射面に近づけると、
zを大きくするとスケールが急激に小さくなります。

焦点距離を大きくすると、つまり視点を投射面から遠ざけると
zを大きくしてもなかなかスケールは小さくなりません。


うーん。よくわからん…。
とりあえずの結論: 焦点距離はスケールを決定付ける定数であり、深く考えない。

3d #1 スケール変換

今から3dの勉強をして見ます。

パースペクティブ=物体が近いか遠いかを知らせる方法、だそうです。
それのひとつの手法として下記があります。

1.遠ざかるにつれて小さくなる
2.遠ざかるにつれ消失点に収束する

パースペクティブを横から見た図、というのが読んでいる本に載っております。
「視点」「投影面」「オブジェクト」
という順番で図示されています。

視点から投影面までの距離をfl (focal length:焦点距離)
投影面からオブジェクトまでの距離をz

とすると、画面上に表示されるオブジェクトのスケールは下記のように表されるそうです。

scale = fl / (fl + z)

投影面という概念がいまいちよく分かりませんが。zに対するscaleの関係は下記の図のようになります。焦点距離はふつう300くらいを使うそうなので300でいきます。
zToScale.gif


図があまりにもダサい。。
zが0だとスケール1、300になるとスケールが0.5、zが600になると0.34
みたいな感じになります。距離とスケールの関係は非線形です。なぜこういう式になるかは分かりませんが、おそらく一般的なのでしょう。深く考えずこれを使っていこうと思います。