public static function slerp( qa:Quaternion, qb:Quaternion, alpha:Number ):Quaternionという風に、引数で渡された二つのクォータニオンの内積を元に回転角を求めている。
{
var qm:Quaternion = new Quaternion();
// Calculate angle between them.
var cosHalfTheta:Number = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
// if qa=qb or qa=-qb then theta = 0 and we can return qa
if(Math.abs(cosHalfTheta) >= 1.0)
{
qm.w = qa.w;
qm.x = qa.x;
qm.y = qa.y;
qm.z = qa.z;
return qm;
}
.............
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import org.papervision3d.core.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.math.*;
import org.papervision3d.scenes.* ;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.cameras.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.shadematerials.* ;
import org.papervision3d.materials.utils.*;
import org.papervision3d.view.*;
import org.papervision3d.render.*;
import org.papervision3d.lights.*;
import org.papervision3d.materials.special.LineMaterial ;
[SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")]
public class SlerpTest2 extends Sprite{
private var renderer:BasicRenderEngine = new BasicRenderEngine();
private var viewport:Viewport3D = new Viewport3D(600, 800, false, true);
private var scene:Scene3D = new Scene3D();
private var camera:FreeCamera3D = new FreeCamera3D();
private var lines:Array = null;
private var cube1:Cube;
private var cube2:Cube;
private var cube3:Cube;
private var timer:Timer=null;
private var cnt:int = 0;
private var q1:Quaternion = new Quaternion(300, 0, 0);
private var q2:Quaternion = new Quaternion(0, 200, 0);
private var angle:Number;
private var tt:Number = 0;
private var fwd:Boolean = true;
public function SlerpTest2():void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addChild(viewport);
camera.y = -300;
camera.z = -1100;
camera.x = 0;
camera.focus = 1100;
camera.zoom = 1;
cube1= new Cube(new MaterialsList({all:new WireframeMaterial(0xff00)}),
100, 200, 300);
scene.addChild(cube1);
var nq1:Quaternion = new Quaternion(q1.x, q1.y, q1.z);
var nq2:Quaternion = new Quaternion(q2.x, q2.y, q2.z);
nq1.normalize();
nq2.normalize();
var dot:Number = Quaternion.dot(nq1,nq2);
angle = Math.acos(dot);
timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
}
private function onTimer(e:*):void{
var qSrc:Quaternion;
var qDst:Quaternion;
if(fwd){
qSrc = q1;
qDst = q2;
}else{
qSrc = q2;
qDst = q1;
}
var t1:Number = Math.sin((1-tt)*angle) / Math.sin(angle);
var t2:Number = Math.sin(tt*angle) / Math.sin(angle);
cube1.x = t1*qSrc.x + t2*qDst.x;
cube1.y = t1*qSrc.y + t2*qDst.y;
cube1.z = t1*qSrc.z + t2*qDst.z;
tt += 0.1;
if (tt > 1){
fwd = !fwd;
tt = 0;
}
renderer.renderScene(scene, camera, viewport);
}
}
}
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import org.papervision3d.core.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.math.*;
import org.papervision3d.scenes.* ;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.cameras.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.shadematerials.* ;
import org.papervision3d.materials.utils.*;
import org.papervision3d.view.*;
import org.papervision3d.render.*;
import org.papervision3d.lights.*;
import org.papervision3d.materials.special.LineMaterial ;
[SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")]
public class SlerpTest22 extends Sprite{
private var renderer:BasicRenderEngine = new BasicRenderEngine();
private var viewport:Viewport3D = new Viewport3D(600, 800, false, true);
private var scene:Scene3D = new Scene3D();
private var camera:FreeCamera3D = new FreeCamera3D();
private var lines:Array = null;
private var cube1:Cube;
private var cube2:Cube;
private var cube3:Cube;
private var timer:Timer=null;
private var cnt:int = 0;
private var q1:Quaternion = new Quaternion(300, 0, 0);
private var q2:Quaternion = new Quaternion(0, 200, 0);
private var nq1:Quaternion = new Quaternion(300, 0, 0);
private var nq2:Quaternion = new Quaternion(0, 200, 0);
private var tt:Number = 0;
private var fwd:Boolean = true;
public function SlerpTest22():void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addChild(viewport);
camera.y = -300;
camera.z = -1100;
camera.x = 0;
camera.focus = 1100;
camera.zoom = 1;
cube1= new Cube(new MaterialsList({all:new WireframeMaterial(0xff00)}),
100, 200, 300);
scene.addChild(cube1);
// core.math.Quaternion.slerp()には正規化したクォータニオンを渡す必要がある
nq1= new Quaternion(q1.x, q1.y, q1.z);
nq2= new Quaternion(q2.x, q2.y, q2.z);
nq1.normalize();
nq2.normalize();
timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
}
private function onTimer(e:*):void{
tt += 0.1;
if (tt > 1){
fwd = !fwd;
tt = 0;
}
var qSrc:Quaternion;
var qDst:Quaternion;
var rate:Number = q1.x / nq1.x;
if(fwd){
qSrc = nq1;
qDst = nq2;
}else{
qSrc = nq2;
qDst = nq1;
}
var q:Quaternion = Quaternion.slerp(qSrc, qDst, tt);
// 計算されたクォータニオンは正規化したものを元にしたクォータニオンなので補正する
cube1.x = q.x * rate;
cube1.y = q.y * rate;
cube1.z = q.z * rate;
renderer.renderScene(scene, camera, viewport);
}
}
}
Author:yamasv@gmail.com
コメント、トラックバック、リンクはお気軽に
-->
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| - | - | - | - | - | 1 | 2 |
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 | - | - | - | - | - | - |