前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)

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

作者头像
菩提树下的杨过
发布于 2018-01-22 07:14:30
发布于 2018-01-22 07:14:30
82400
代码可运行
举报
运行总次数:0
代码可运行

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import flash.events.Event;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;

var isAngleChangeing = false;

var txtX:TextField,txtY:TextField,txtZ:TextField,txtPosZ:TextField,txtFieldOfView:TextField,txtInfo:TextField,txtCenter:TextField,txtFocusLength:TextField;
txtX = new TextField();
txtX.text = "rotationX:";
txtY = new TextField();
txtY.text = "rotationY:";
txtZ = new TextField();
txtZ.text = "rotationZ:";
txtPosZ = new TextField();
txtPosZ.text = "Z:";
txtFieldOfView = new TextField();
txtFieldOfView.text = "视角:";
txtCenter = new TextField();
txtCenter.text = "消失点:"
txtFocusLength = new TextField();
txtFocusLength.text = "焦距:";
txtX.y = txtY.y = txtZ.y = 5;
txtX.x = txtPosZ.x = 10;
txtPosZ.y = txtX.y + 26;
txtPosZ.x +=  40;
txtY.x = txtX.x + 180;
txtZ.x = txtY.x + 180;
txtFieldOfView.x = txtPosZ.x + 160;
txtFieldOfView.y = txtPosZ.y;
txtCenter.x = txtFieldOfView.x + 170;
txtCenter.y = txtPosZ.y;
txtInfo = new TextField();
txtInfo.text="";
txtFocusLength.x = txtX.x + 25;
txtFocusLength.y = txtPosZ.y + 25;

var imgBD:BitmapData = new ImgSample();
var img:Bitmap = new Bitmap(imgBD);
trace("img.width=",img.width,",img.height=",img.height);

var imgSprite:Sprite = new Sprite();
img.x =  -  img.width / 2;
img.y =  -  img.height / 2;
imgSprite.addChild(img);
trace("imgSprite.width=",imgSprite.width,",imgSprite.height=",imgSprite.height);

var containerSprite:Sprite = new Sprite();
containerSprite.addChild(imgSprite);
imgSprite.x = img.width / 2;
imgSprite.y = img.height / 2;

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

containerSprite.x = stage.stageWidth / 2 - containerSprite.width / 2;
containerSprite.y = stage.stageHeight / 2 - containerSprite.height / 2;
containerSprite.z = 50;

var silderX:SimpleSlider = new SimpleSlider(0,360,0);
silderX.x = txtX.x + 160;
silderX.y = txtX.y + 7;
silderX.rotation = 90;

var silderY:SimpleSlider = new SimpleSlider(0,360,0);
silderY.x = txtY.x + 160;
silderY.y = silderX.y;
silderY.rotation = 90;

var silderZ:SimpleSlider = new SimpleSlider(0,360,0);
silderZ.x = txtZ.x + 160;
silderZ.y = silderX.y;
silderZ.rotation = 90;

var silderPosZ:SimpleSlider = new SimpleSlider(-200,200,50);
silderPosZ.x = txtX.x + 160;
silderPosZ.y = silderX.y + 25;
silderPosZ.rotation = 90;

var silderFieldOfView:SimpleSlider = new SimpleSlider(0.1,179.9,90);
silderFieldOfView.x = silderPosZ.x + 180;
silderFieldOfView.y = silderPosZ.y;
silderFieldOfView.rotation = 90;

var silderCenterPos:SimpleSlider = new SimpleSlider(150,400,275);
silderCenterPos.x = silderFieldOfView.x + 180;
silderCenterPos.y = silderPosZ.y;
silderCenterPos.rotation = 90;

var silderFocusLength:SimpleSlider = new SimpleSlider(100,500,300);
silderFocusLength.x = silderPosZ.x ;
silderFocusLength.y = silderPosZ.y + 25;
silderFocusLength.rotation = 90;

addChild(txtX);
addChild(txtY);
addChild(txtZ);
addChild(txtPosZ);
addChild(txtFieldOfView);
addChild(txtInfo);
addChild(txtCenter);
addChild(txtFocusLength);
addChild(silderX);
addChild(silderY);
addChild(silderZ);
addChild(silderPosZ);
addChild(silderFieldOfView);
addChild(silderCenterPos);
addChild(silderFocusLength);

silderX.addEventListener(Event.CHANGE,silderXChangeHandler);
silderY.addEventListener(Event.CHANGE,silderYChangeHandler);
silderZ.addEventListener(Event.CHANGE,silderZChangeHandler);
silderPosZ.addEventListener(Event.CHANGE,silderPosZChangeHandler);
silderFieldOfView.addEventListener(Event.CHANGE,silderFieldOfViewChangeHandler);
silderFieldOfView.addEventListener(MouseEvent.MOUSE_UP,function(){isAngleChangeing = false});
silderCenterPos.addEventListener(Event.CHANGE,silderCenterPosChangeHandler);
silderFocusLength.addEventListener(Event.CHANGE,silderFocusLengthChangeHandler);


function showTxtInfo(s:SimpleSlider){
	txtInfo.text = s.value.toString().substr(0,5);
	txtInfo.x = mouseX + 20;
	txtInfo.y = s.y + 5;
}

function silderXChangeHandler(e:Event):void {
	imgSprite.rotationX = silderX.value;
	showTxtInfo(silderX);
}

function silderYChangeHandler(e:Event):void {
	imgSprite.rotationY = silderY.value;
	showTxtInfo(silderY);
}

function silderZChangeHandler(e:Event):void {
	imgSprite.rotationZ = silderZ.value;
	showTxtInfo(silderZ);
}

function silderPosZChangeHandler(e:Event):void {
	containerSprite.z = silderPosZ.value;
	showTxtInfo(silderPosZ);
}


function silderFieldOfViewChangeHandler(e:Event):void {
	doPerspectiveProjection();
	showTxtInfo(silderFieldOfView);
	isAngleChangeing = true;
}

function silderCenterPosChangeHandler(e:Event):void {
	doPerspectiveProjection();
	showTxtInfo(silderCenterPos);
}

function silderFocusLengthChangeHandler(e:Event):void {
	doPerspectiveProjection();
	showTxtInfo(silderFocusLength);
}

function doPerspectiveProjection():void{
	var pp:PerspectiveProjection=new PerspectiveProjection();
	pp.fieldOfView = silderFieldOfView.value;
	if (!isAngleChangeing){
		pp.focalLength  = silderFocusLength.value;	
	}
	//trace(pp.focalLength);
	pp.projectionCenter = new Point(silderCenterPos.value,silderCenterPos.value);
	containerSprite.transform.perspectiveProjection = pp;
	
}

doPerspectiveProjection();

var txtAuthor:TextField = new TextField();
txtAuthor.htmlText ="<a href='http://yjmyzz.cnblogs.com/' target='_blank'>by 菩提树下的杨过</a>";
addChild(txtAuthor);
txtAuthor.y = txtFocusLength.y;
txtAuthor.x = 425;
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.如何用代码从库里取出一张图片?

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var imgBD:BitmapData = new ImgSample();//从库中取出一张图片
var img:Bitmap = new Bitmap(imgBD);

得到一个图片的Bigmap实例

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2010-05-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Flash/Flex学习笔记(52):使用TweenLite
TweenLite是第三方出品的专用于各种缓动动画的类库,其性能据说已经超过了Adobe官方的Tween. 从网上找到了一篇中文的说明文档:http://files.cnblogs.com/yjmyzz/tweenLite%e4%b8%ad%e6%96%87%e6%89%8b%e5%86%8c%e4%b8%8e%e5%8f%82%e6%95%b0%e8%af%b4%e6%98%8e.pdf 这是官方的测试示例: AS3类库下载: http://files.cnblogs.com/yjmyzz/greenso
菩提树下的杨过
2018/01/22
7420
Flash在线拍摄用户头象
很多网站在上传用户头象时,除了传统方式上传外,都支持在线摄像头拍照并做简单编辑,完成之后再将图象数据提交到服务端(比如ASP.Net),这几天正好需要这个功能,研究了下,思路如下: 1、先获取摄像头视频 2、利用BitmapData.draw来对视频截图 3、在截图上,放一个方块允许用户手动调整位置,同时允许截图做缩放 4、用户调整完成后,对指定区域的BitmapData做copyPixes处理(即拷贝指定区域的像素) 5、将上一步得到的新BitmapData进行Jpeg编码压缩,然后再转到base64字符
菩提树下的杨过
2018/01/23
1.1K0
Flash在线拍摄用户头象
Flash/Flex学习笔记(46):正向运动学
所谓"正向运动学"通俗点讲就是把几个连接部件的一端固定起来,另一个端可以自由(向前/向外)运动。比如人的行走,单个下肢可以理解为脚连接小腿,小腿连接大腿,大腿连接腰。行走的过程,相当于二条腿相对固定于腰部,大腿运动驱动小腿,小腿又驱动脚,从而带动整个连接系统的一系列运动。 先来一个基本的关节类Segment:(就是一个圆角矩形+二个小圆圈) package { import flash.display.Sprite; import flash.geom.Point; public class Seg
菩提树下的杨过
2018/01/23
6200
Flash/Flex学习笔记(46):正向运动学
Flash/Flex学习笔记(42):坐标旋转
坐标旋转是个啥概念呢? 如上图,(蓝色)小球 绕某一中心点旋转a角度后,到达(红色)小球的位置,则红色小球相对中心点的坐标为: x1 = dx * cos(a) - dy * sin(a) y1 = 
菩提树下的杨过
2018/01/23
7060
Flash/Flex学习笔记(42):坐标旋转
Flash/Flex学习笔记(41):碰撞检测
碰撞检测基本上可能分为二类:对象与对象的碰撞检测、对象与点的碰撞检测 为了方便测试,先写一个box类(生成一个小矩形) package { import flash.display.Sprite; public class Box extends Sprite { private var w:Number; private var h:Number; private var color:uint; public var vx:Number=0; public var v
菩提树下的杨过
2018/01/19
9660
Flash/Flex学习笔记(41):碰撞检测
flash/flex 与 FluorineFx通讯之Hello World!
Bēniaǒk兄弟的Flex与.NET互操作(六):Flex和.NET协同开发利器FluorineFx 是基于vs2008 + flex builder3的,不知道什么原因,我在vs2010 + flash builder4 上试了几次,总是不成功(也许晚上应该自我检讨下人品鸟),于是有了这一篇东东,算是对 vs2010/flash builder4环境下的一个补充吧 .net的服务端依照参照silverlight获取外部数据的另一种选择:FluorineFx 里的做法,在TestLib.cs里定义一个方法
菩提树下的杨过
2018/01/23
9300
flash/flex 与 FluorineFx通讯之Hello World!
发布一个轻量级的滑块控件
比系统自带的组件体积要小很多,而且支持进度条显示(在做播放器时,显示缓冲进度很有用哦),另外也支持三角形的音量调整显示 使用示例: package { import flash.display.SimpleButton; import flash.display.Sprite; import flash.events.Event; import flash.text.TextField; [SWF(width=150, height=130)] public class SliderTest
菩提树下的杨过
2018/01/23
1.1K0
Flash/Flex学习笔记(23):运动学原理
先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class Ball extends Sprite{ private var radius:Number ;//半径 private var color:uint;//颜色 public function Ball(r:Number=50,c:uint=0xff0000){ this.radius = r; this.color
菩提树下的杨过
2018/01/19
7910
Flash/Flex学习笔记(36):自己动手实现一个滑块控件(JimmySilder)
先看最终的演示: 滑块条的应用实在太广泛了:mp3播放器中声量的大小控制,视频播放时的画面亮度调节,阅读新闻时字体大小的实时调整,对象的大小互动控制... 分析: 1.任何一个滑块条控件的UI部分,基本上可以分为:背景滑块条 + 滑块按钮 二个部分 所以我分成了三部分: JimmySilderBar(背景条),JimmySilderButton(拖动钮),JimmySilder(真正的滑动控件,将前二个组合在一起),为了重用,这三个部分都做成MovieClip元件放在库里,这样以后要换风格或颜色时,只要在库
菩提树下的杨过
2018/01/23
1.2K0
Flash/Flex学习笔记(36):自己动手实现一个滑块控件(JimmySilder)
Flash/Flex学习笔记(25):摩擦力与屏幕环绕
摩擦力: 假如一个物体在某个方向上沿直线运行,摩擦力会使该方向上的速度越来越小,直到停止。 上图示意了该过程,物体以moveAngle角度正向运动,最终的速度speed矢量为vx矢量与vy矢量的矢量
菩提树下的杨过
2018/01/19
5430
Flash/Flex学习笔记(25):摩擦力与屏幕环绕
Flash/Flex学习笔记(24):粒子效果
粒子爆炸: 仍然要用到以前的小球类,不过稍加改造 package { import flash.display.Sprite; //小球 类 public class Ball extends Sprite { public var radius:uint;//半径 public var color:uint;//颜色 public var vx:Number=0;//x轴速度 public var vy:Number=0;//y轴速度 public function Bal
菩提树下的杨过
2018/01/23
6760
Flash/Flex学习笔记(48):反向运动学(下)
先要复习一下三角函数与余弦定理: 对于直角三角形,三边长a,b,c与三个角A,B,C的关系如下: 正弦函数: 余弦函数: 正切函数: 反正切函数:(好象现在的教科书里改叫“余切”函数)   或 勾股
菩提树下的杨过
2018/01/23
5790
Flash/Flex学习笔记(48):反向运动学(下)
“AS3.0高级动画编程”学习:第二章转向行为(上)
因为这一章的内容基本上都是涉及向量的,先来一个2D向量类:Vector2D.as (再次强烈建议不熟悉向量运算的童鞋,先回去恶补一下高等数学-07章空间解释几何与向量代数.pdf) package { import flash.display.Graphics; public class Vector2D { private var _x:Number; private var _y:Number; //构造函数 public function Vector2D(x:Number
菩提树下的杨过
2018/01/23
1.4K0
“AS3.0高级动画编程”学习:第二章转向行为(上)
Flash/Flex学习笔记(17):按键捕获
先来看简单的单个按键捕获: package { import flash.display.Sprite; import fl.controls.Label; import flash.events.KeyboardEvent; import flash.ui.Keyboard; public class KeyDown extends Sprite { private var lbl:Label; private var ball:Sprite; public functi
菩提树下的杨过
2018/01/23
8640
Flash/Flex学习笔记(32):播放音乐并同步显示lyc歌词(适用于Silverlight)
题外话:个别朋友总是问我同样的问题,做为一名c#/silverlight程序员为啥还要学flash ? 回 答:看日本片时,就不能对照看欧美的么? 不体会日本的细腻,又怎能感觉到欧美的粗放;同样都是w
菩提树下的杨过
2018/01/23
8000
Flash/Flex学习笔记(39):弹性运动
动画中的弹性运动 从视觉效果上接近 物理经典力学中的单摆运动或弹簧(胡克定律F=Kx)振动 先看下面的模拟演示: 规律: 小球先从出发点(初始为最左侧)向目标点(中心点)加速狂奔,奔的过程中速度越来越大,但加速度越来越小,等经过目标点时,发现速度太大刹不住车(此时速度达到最大值,但加速度减为0),奔过头了!于是加速度发生逆转,从0开始变为负值,从而导致速度越来越小,等速度减到0时,也奔到了最右侧(此时负加速度也达到最大值),然后在负加速度的影响下,开始掉头又狂奔....这样不断下去,直接摩擦力让它筋疲力尽,
菩提树下的杨过
2018/01/19
6550
As3.0中的位图(Bitmap/BitmapData)编程
As3.0中的位图(Bitmap/BitmapData)编程功能十分丰富,下面这些是官方文档上的基本示例: 1.位图使用(模糊)滤镜 //创建一个矩形区域的BitmapData var bmd:BitmapData = new BitmapData(80, 30, false, 0xefefef); //画个红色的矩形 var rect:Rectangle = new Rectangle(20, 10, 40, 10); bmd.fillRect(rect, 0xFF0000); //找到红色矩形的右上
菩提树下的杨过
2018/01/22
1.7K0
近期学习flash as3总结
       flex 3 比较符合程序员的习惯,尤其是对Java程序员来说,Eclipse 太熟悉了,不过我觉得不能开发多帧的程序是flex 的最大缺点,也可能我孤陋寡闻,没找到开发多帧程序的方式
py3study
2020/01/06
4430
as3与php 上传多张图片demo
2、在一次添加的图片中如果超出最大上传数,忽略本次选中的所有图片(又得重新选一次,此现象普通存在于目前各大网站的flash批量上传中)
meteoric
2018/11/15
2.8K0
egret 学习笔记
继承自 DisplayObjectContainer > DisplayObject。
tonglei0429
2021/06/08
1.8K0
egret 学习笔记
相关推荐
Flash/Flex学习笔记(52):使用TweenLite
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验