您的位置:首页 > 其它

Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)

2010-11-22 17:49 316 查看
Flash/Flex学习笔记(49):3D基础 里已经介绍了3D透视的基本原理,不过如果每次都要利用象该文中那样写一堆代码,估计很多人不喜欢,事实上AS3的DisplayObject类已经内置了z坐标、rotationX、rotationY、rotationZ属性,再加上PerspectiveProjection类用于处理透视转换,基本上可以满足大多数的3D要求。

001

import
flash.events.Event;


002

import
flash.display.Sprite;


003

import
flash.text.TextField;


004

import
flash.events.MouseEvent;


005

import
flash.text.TextFieldAutoSize;


006


007

var
isAngleChangeing =
false
;


008


009

var
txtX:TextField,txtY:TextField,txtZ:TextField,txtPosZ:TextField,txtFieldOfView:TextField,txtInfo:TextField,txtCenter:TextField,txtFocusLength:TextField;


010

txtX =
new
TextField();


011

txtX.text =
"rotationX:"
;


012

txtY =
new
TextField();


013

txtY.text =
"rotationY:"
;


014

txtZ =
new
TextField();


015

txtZ.text =
"rotationZ:"
;


016

txtPosZ =
new
TextField();


017

txtPosZ.text =
"Z:"
;


018

txtFieldOfView =
new
TextField();


019

txtFieldOfView.text =
"视角:"
;


020

txtCenter =
new
TextField();


021

txtCenter.text =
"消失点:"


022

txtFocusLength =
new
TextField();


023

txtFocusLength.text =
"焦距:"
;


024

txtX.y = txtY.y = txtZ.y =
5
;


025

txtX.x = txtPosZ.x =
10
;


026

txtPosZ.y = txtX.y +
26
;


027

txtPosZ.x +=
40
;


028

txtY.x = txtX.x +
180
;


029

txtZ.x = txtY.x +
180
;


030

txtFieldOfView.x = txtPosZ.x +
160
;


031

txtFieldOfView.y = txtPosZ.y;


032

txtCenter.x = txtFieldOfView.x +
170
;


033

txtCenter.y = txtPosZ.y;


034

txtInfo =
new
TextField();


035

txtInfo.text=
""
;


036

txtFocusLength.x = txtX.x +
25
;


037

txtFocusLength.y = txtPosZ.y +
25
;


038


039

var
imgBD:BitmapData =
new
ImgSample();


040

var
img:Bitmap =
new
Bitmap(imgBD);


041

trace
(
"img.width="
,img.width,
",img.height="
,img.height);


042


043

var
imgSprite:Sprite =
new
Sprite();


044

img.x =  -  img.width /
2
;


045

img.y =  -  img.height /
2
;


046

imgSprite.addChild(img);


047

trace
(
"imgSprite.width="
,imgSprite.width,
",imgSprite.height="
,imgSprite.height);


048


049

var
containerSprite:Sprite =
new
Sprite();


050

containerSprite.addChild(imgSprite);


051

imgSprite.x = img.width /
2
;


052

imgSprite.y = img.height /
2
;


053


054

addChild(containerSprite);


055

trace
(
"containerSprite.width="
,containerSprite.width,
",containerSprite.height="
,containerSprite.height);


056


057

containerSprite.x = stage.stageWidth /
2
- containerSprite.width /
2
;


058

containerSprite.y = stage.stageHeight /
2
- containerSprite.height /
2
;


059

containerSprite.z =
50
;


060


061

var
silderX:SimpleSlider =
new
SimpleSlider(
0
,
360
,
0
);


062

silderX.x = txtX.x +
160
;


063

silderX.y = txtX.y +
7
;


064

silderX.rotation =
90
;


065


066

var
silderY:SimpleSlider =
new
SimpleSlider(
0
,
360
,
0
);


067

silderY.x = txtY.x +
160
;


068

silderY.y = silderX.y;


069

silderY.rotation =
90
;


070


071

var
silderZ:SimpleSlider =
new
SimpleSlider(
0
,
360
,
0
);


072

silderZ.x = txtZ.x +
160
;


073

silderZ.y = silderX.y;


074

silderZ.rotation =
90
;


075


076

var
silderPosZ:SimpleSlider =
new
SimpleSlider(-
200
,
200
,
50
);


077

silderPosZ.x = txtX.x +
160
;


078

silderPosZ.y = silderX.y +
25
;


079

silderPosZ.rotation =
90
;


080


081

var
silderFieldOfView:SimpleSlider =
new
SimpleSlider(
0.1
,
179.9
,
90
);


082

silderFieldOfView.x = silderPosZ.x +
180
;


083

silderFieldOfView.y = silderPosZ.y;


084

silderFieldOfView.rotation =
90
;


085


086

var
silderCenterPos:SimpleSlider =
new
SimpleSlider(
150
,
400
,
275
);


087

silderCenterPos.x = silderFieldOfView.x +
180
;


088

silderCenterPos.y = silderPosZ.y;


089

silderCenterPos.rotation =
90
;


090


091

var
silderFocusLength:SimpleSlider =
new
SimpleSlider(
100
,
500
,
300
);


092

silderFocusLength.x = silderPosZ.x ;


093

silderFocusLength.y = silderPosZ.y +
25
;


094

silderFocusLength.rotation =
90
;


095


096

addChild(txtX);


097

addChild(txtY);


098

addChild(txtZ);


099

addChild(txtPosZ);


100

addChild(txtFieldOfView);


101

addChild(txtInfo);


102

addChild(txtCenter);


103

addChild(txtFocusLength);


104

addChild(silderX);


105

addChild(silderY);


106

addChild(silderZ);


107

addChild(silderPosZ);


108

addChild(silderFieldOfView);


109

addChild(silderCenterPos);


110

addChild(silderFocusLength);


111


112

silderX.addEventListener(Event.CHANGE,silderXChangeHandler);


113

silderY.addEventListener(Event.CHANGE,silderYChangeHandler);


114

silderZ.addEventListener(Event.CHANGE,silderZChangeHandler);


115

silderPosZ.addEventListener(Event.CHANGE,silderPosZChangeHandler);


116

silderFieldOfView.addEventListener(Event.CHANGE,silderFieldOfViewChangeHandler);


117

silderFieldOfView.addEventListener(MouseEvent.MOUSE_UP,
function
(){isAngleChangeing =
false
});


118

silderCenterPos.addEventListener(Event.CHANGE,silderCenterPosChangeHandler);


119

silderFocusLength.addEventListener(Event.CHANGE,silderFocusLengthChangeHandler);


120


121


122

function
showTxtInfo(s:SimpleSlider){


123

txtInfo.text = s.value.toString().substr(
0
,
5
);


124

txtInfo.x = mouseX +
20
;


125

txtInfo.y = s.y +
5
;


126

}


127


128

function
silderXChangeHandler(e:Event):
void
{


129

imgSprite.rotationX = silderX.value;


130

showTxtInfo(silderX);


131

}


132


133

function
silderYChangeHandler(e:Event):
void
{


134

imgSprite.rotationY = silderY.value;


135

showTxtInfo(silderY);


136

}


137


138

function
silderZChangeHandler(e:Event):
void
{


139

imgSprite.rotationZ = silderZ.value;


140

showTxtInfo(silderZ);


141

}


142


143

function
silderPosZChangeHandler(e:Event):
void
{


144

containerSprite.z =silderPosZ.value;


145

showTxtInfo(silderPosZ);


146

}


147


148


149

function
silderFieldOfViewChangeHandler(e:Event):
void
{


150

doPerspectiveProjection();


151

showTxtInfo(silderFieldOfView);


152

isAngleChangeing =
true
;


153

}


154


155

function
silderCenterPosChangeHandler(e:Event):
void
{


156

doPerspectiveProjection();


157

showTxtInfo(silderCenterPos);


158

}


159


160

function
silderFocusLengthChangeHandler(e:Event):
void
{


161

doPerspectiveProjection();


162

showTxtInfo(silderFocusLength);


163

}


164


165

function
doPerspectiveProjection():
void
{


166

var
pp:PerspectiveProjection=
new
PerspectiveProjection();


167

pp.fieldOfView = silderFieldOfView.value;


168

if
(!isAngleChangeing){


169

pp.focalLength  = silderFocusLength.value;


170

}


171

//trace(pp.focalLength);


172

pp.projectionCenter =
new
Point(silderCenterPos.value,silderCenterPos.value);


173

containerSprite.transform.perspectiveProjection = pp;


174


175

}


176


177

doPerspectiveProjection();


178


179

var
txtAuthor:TextField =
new
TextField();


180

txtAuthor.htmlText =
"<a href='http://yjmyzz.cnblogs.com/' target='_blank'>by 菩提树下的杨过</a>"
;


181

addChild(txtAuthor);


182

txtAuthor.y = txtFocusLength.y;


183

txtAuthor.x =
425
;


184

txtAuthor.autoSize = TextFieldAutoSize.LEFT;


稍加解释:

z坐标:即对象在z轴上的坐标,flash默认采用的是右手三维坐标,也就是说z值越大,物体越小

rotaionX,rotationY,rotationZ:即对象绕着x,y,z轴旋转的角度

PerspectiveProjection对象的三个属性:

1.focalLength 即焦距,使用效果上貌似焦距越大,物体也越大(?跟常规理解的不同),而且据官方帮助上讲:在透视转换过程中,将使用视野的角度和舞台的高宽比(舞台宽度除以舞台高度)来自动计算
focalLength


2.fieldOfView 即观察点的三维"视角"(0到180之间的值),怎么理解我还没想好,不过在使用效果上,如果当物体的z轴坐标不为0时,该值越大,物体的扭曲和形变越夸张,而且动态调整该值时focalLength值也会自动重新计算。(所以如果用代码写死了focalLength,不管如何调整fieldOfView都是看不到效果的)

3.projectionCenter:即3D透视中的消失点,当z轴坐标趋近于无限大时,物体越趋向于该点(消失)。

最后:上面的代码中暗藏了二个小技巧

1.为啥要先把图片放到imgSprite中,然后再将imgSprite又放到containerSprite中?

因为旋转时有一个旋转的中心点,而Flash默认这个中心就是对象的左顶点,即(0,0)位置,用二个sprite嵌套后,再配合坐标的设定,巧妙的将中心点正好移动到了图片中心,如下图:



2.如何用代码从库里取出一张图片?



如上图,关键在于导入图片时要指定“类”名,这样在代码中就可以用

1

var
imgBD:BitmapData =
new
ImgSample();
//从库中取出一张图片


2

var
img:Bitmap =
new
Bitmap(imgBD);


得到一个图片的Bigmap实例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: