As3 Matrix 理解与应用

TheMatrixWallpaper800

一、介绍

Matrix 字面意思是矩阵, 是一个数学概念。这个词在本科线性代数里有详细说明,它是数的一个排列,支持好多种数学运算!在flash里,在3D运算中,矩阵 真的是无处不在。flash中,你要使一个可显示对象(DisplayObject )旋转,倾斜,调位置你都可以通过矩阵来完成,虽然你还有其他更简单的方法,就是通过修改rotation, x, y 等值来达到同样的目的。在每个显示对象中,都有一个属性:transform. 这里就包含了显示对象的各种变换,其中一项,就是matrix! 可见matrix在flash中也有重要的作用。

二、为什么是矩阵

矩阵对于很多数学恐惧者来说,很让人无法直视, 真的很让人头痛!但是它却在计算机图形学里起着很重要的作用。我们从简单说起!

2.1 坐标系统

在我们的学习中,就已经深刻的学习了坐标系统的概念,要分析空间物体及其对应关系,就离不开坐标系这个概念!我们最熟悉的是笛卡尔坐标系, 直角坐标系!在坐标系里又可以找到很多概念,这些概念对于我们理解这矩阵有着很重要的作用。 比如说,物体坐标系, 旋转坐标系,世界坐标系等。

世界坐标系,简单来说,它是空间里处于全局位置,永远不变的坐标系。举个例子,我们要研究小猫在房间里的运动路径,这时我们可以选择房间里的一个角落来作为我们的世界坐标系。 物体坐标系,就是以处于世界坐标系下的一个物体上的某一点构成的坐标系,假如我们选择小猫正常站立形态下后脚作为原点建立一个直角坐标系,那么,这个坐标系就是小猫的物体坐标系,这个物体坐标系相对世界坐标系而言,它会随着猫的运动而运动!

2.2 物体变换

我们选定了物体坐标系, 小猫一天中会在房间里各处走动,或跑,或跳,或睡觉等,那么,这时的小猫就相对世界坐标系而言,它发生了一些变换,可能包括:平移,旋转,当然还可能包括缩放(缩着身子)。 假如小猫在进食时在身上沾了一粒米,那么,在小猫在世界坐标系里进行变换时,这粒米相对相对世界坐标系又是怎么一个情形呢? 这就相当于在数学上一个物体从一个坐标系变换到另一个坐标系下,如何确定其位置的问题,对于这个问题,用矩阵可以很好的来解决这个问题!

在flash里,矩阵matrix也是一样用于处理坐标变换的问题。相信大家可能曾经会想过一个问题。 一个显示对象有宽,有高,那么对于这些内容是如何分层次的画出来的,又如何确定物体内部每个点在舞台上的位置的呢? 没错,就是通过坐标变换来实现的!

三、矩阵

flash里 矩阵用于将点从一个坐标系转换到另一个坐标系, 使用下面的方程:

clip_image002

其中P代表变换后的坐标点, N代表变换前坐标点(都是以列向量的形式)。

显示对象的transform属性的matrix就是这个M, 它用于将物体坐标系里的点变换到显示对象父坐标中。

image

这个M是一个3维矩阵,如下所示:

Matrix class properties in matrix notation showing    assumed values for u, v, and w

转换过程如下:

clip_image002[4]

其中a, d 影响显示对象的缩放, c, d 影响显示对象的倾斜, a, b, c, d同时影响显示对象的旋转。 tx, ty 代表显示对象相对于父对象的位置偏移!如果clip_image002[6] 都为0 的话,

那么clip_image002[8]就是 clip_image002[10] 所以说, tx, ty 就是显示对象的坐标。

四、应用

1. 获取对象里某一点在父对象中的位置。

var p:Point = new Point( x0, y0 );
p = displayObject.transform.matrix.transformPoint( p );

2. 绘制渐变图

代码示例略

3. 中心旋转

public function rotateAroundCenter (ob:DisplayObject, angleDegrees:Number):void
{
    var matrix:Matrix = ob.transform.matrix; 

    var rect:Rectangle = ob.getBounds(ob.parent); 

    matrix.translate(- (rect.left + (rect.width/2)), - (rect.top + (rect.height/2))); 

    matrix.rotate((angleDegrees/180)*Math.PI); 

    matrix.translate(rect.left + (rect.width / 2), rect.top + (rect.height / 2));

    ob.transform.matrix = matrix;
}

4. 绕点旋转

// get matrix object from your MovieClip (mc)
var m:Matrix = mc.transform.matrix;

// set the point around which you want to rotate your MovieClip (relative to the MovieClip position)
var point:Point = new Point(10, 10);

// get the position of the MovieClip related to its origin and the point around which it needs to be rotated
point = m.transformPoint(point);
// set it
m.translate( -point.x, -point.y);

// rotate it of 30°
m.rotate(30 * (Math.PI / 180));

// and get back to its "normal" position
m.translate(point.x, point.y);

// finally, to set the MovieClip position, use this
mc.transform.matrix = m;

// or this
mc.x = m.tx;
mc.y = m.ty;
mc.rotation += 30;

值得注意的是, 你通过Matrix的rotate方法旋转得到的效果与你通过显示对象的rotation属性得到的是不样的!这是因为 matrix.rotate 以父对象的原点为旋转中心,旋转的是物体坐标系, 所以,通过rotate是会改变tx, ty的。 如下图所示:

image

希望本文章能够帮到你!转载请注明梦溪笔记!

flash 动态嵌入字体, 嵌入你要的字符

一、简单

在使用As3 开发软件的过程,我们会遇到的比较头痛的一个问题是字体的处理!特别是针对中文这样的语言!

我们都知道嵌入式的字体比非嵌入的字体在效果上好很多, 所以我们希望在很多项目上能够使用嵌入的字体。

通常的嵌入字体的做法是通过flash cs 这些工具 来进行字体生成,如果你要生成一个字体,而这个字体可能的符号是所有字符集的时候,这个字体文件将会变得特别大,如果你要放在网络环境中,那直接就是一个噩梦!要在网络上加载1M文件会让用户在等待中发狂。。。

 

一个可行的解决方案是,用户用到了某个字体的特定字符,我们就只把这个字符嵌入到swf中,这样生成的文件将会小很多,文件的大小以出现的字符数量定!而且这样的好处就是用户可以使用他机器上的任何一个字体。 那么这个如何在技术上实现呢?

二、技术实现

2.1 Haxe

有一种开源的语言叫Haxe, 这种语言超NB, 她只要你写一次,就可以直接编译成各种语言, 诸如:c++, php, as3, c#, javascript, NekoVM, java 等, 让人觉得不可思议。 她有actionscript 3 的传统,所以,她对flash, as3 有超强的支持能力,使得你可以用她了做很多关于as3,swf等的事情,就比如说我们现在讨论的动态生成嵌入了字体的swf文件。这是一件多么有意思的事情

2.2 关于swf

SWF是一种文件格式,大家都知道的,而有意思的是这个格式是开放标准的,意思是,你可以查到关于SWF这个文件格式的任意一个规范,如果你够NB,你也可以阅读这个规范,并根据这个规范写出你自己的swf播放器,swf生成器,并且编辑swf! 你所知道的一些软件,比如说硕思这个swf反编译工具 就是根据SWF文件格式来进行反编译工具的,你也可以模仿它来写一个自己的swf加密混淆或者是反编译工具。

2.3 动态生成技术

Google Code 上有一个开源项目,她叫hxswfml, 她是基于Haxe 而来的一个项目, 简单的来说,她可以让你写一个xml文件,然后通过她,把这个xml文件编译成swf文件,够COOL吧!因为 Haxe 可以编译成php, js 等语言,所以,这能够让你在你的网站项目中,动态的生成 swf文件, 一下子让你的网站充满了神奇! 我们可以用她来完成动态生成swf字体文件的任务!在下面体验一下吧!

 

在文本区域内输入你需要的字符, 写上字体名( FontName 用于指定 字体名,类似于css中的font-family ), 写上调用时的类名( className 用于指定生成这个字体的类名,用于加载字体时获取字体引用 ) , 写完这些后,点击 Generate SWF 来生成你的swf 字体文件。 Test Font 用于测试字体 文件是不是有效 微笑 快来体验一下吧

 

2.4 在项目中使用

如果你的项目是基于AIR技术, 你可以直接把hxswfml 编译成swc文件,在项目中使用即可,我这里给你提供一个已经编译好的AIR 可用swc 文件flash as3 可以swc 文件.

如果你是基于客户端的技术,这时候你要把hxswfml编译成exe文件, 这个exe文件可以在该项目的下载中找到,不过要注意:

如果你直接使用下载的hxswfml.exe 你会发现运行不了,出现一个加载库失败提示

Error : Could not load module std@parse_xml__2

这是因为hxswfml需要依赖几个动态连接库,你只需要把这几个dll放到hxswfml.exe目录下,就可直接运行了.

如果你不知道去哪里找这些库,我为你准备好了,点击下载就ok

 

 

2.5 编译cpp 配置

如果需要自己编译这个hxswfml.exe文件,那么你需要配置工作环境,你可以根据这篇文章的指导来进行, HXCPP配置

结束语

到这里, 你已经了解了如何去实现动态生成所需要的swf字体, 希望这篇文章能为你解决问题!

如果你有什么问题,可以联系! 至于联系方式,相信你会找到 微笑

 

本文章为原创!转载请注明作者及出处!

smaile

堵车?你自找的!

(文/William Beaty)公路上两车道并为一车道的地方最容易发生交通堵塞。如果车辆之间没有较大的间距,就无法并道。因此,在行驶时与前面的车辆保持较大距离的司机,能够很好地缓解这种状况。

左图展示的是通常的驾驶情况,车与车之间都挨得紧紧的,在并道时除了最开头的那辆车,其他的车都没法儿动。注意到它们开得有多慢没?

右图显示的则是很少见的驾驶习惯,这些司机喜欢让别人在自己前面并道,并且常常与前面的车保持很大一段距离,遇到拥堵时也一样,这使得并道很容易。看看他们的行驶速度有多快。

 

要缓解并道时发生的拥堵,可以: 

  • 驾驶时与前车保持较大的距离;
  • 让一辆、两辆甚至三辆车在你前面并道;
  • 如果完全堵住了,在你前面留出两个车长的距离;
  • 不要缩短你与前车间的距离来“惩罚”在你前面插队并道的司机。

此外,令人吃惊的是,没有必要人人都这样。在高峰时期,只要有几个司机一直与前车保持较大距离,车流就可以合并,不会出现左图的情况。

是,没错,只是在你的车前空出一大段距离,并不能解决所有的问题。路上车多时,行驶速度必然会变慢。但是,采取这些特殊的驾驶方式,就可以大堵化小、小堵化了。由于许多交通拥堵都是在合并车道时出现的,单个司机的行为就能改善大家的拥堵状况。

 

 

心急开快车,反而放大拥堵波

好多年以前,我会在上下班高峰时期,开车走西雅图的 I-520州际高速公路,一路上总是走了停、停了走。于是我决定做个试验。一天,在我开始撞上那种常见的“拥堵波”时,我便决定放慢驾驶速度。不是像其他人那样拼命往前冲、最后被堵上,我决定尽量保持一个平均时速。这样,渐渐地我就在自己面前空出了一大段距离。我还算好了时间,在要撞上下一波红绿灯前的“拥堵波”时,绿灯就已经亮了,这样我就不必踩刹车。前面空着一大截开车的感觉是很奇怪,但我知道,我开的速度并不比其他人慢。有时候我时间掐得恰到好处,就一直都不用踩刹车,但有些时候我也会开得太快或太慢,这时遇上红绿灯就只好停下来。那天晚上有很多这样的“波”,一路上我有许多机会来提高自己的技术。
就这么开了差不多有半个小时。要进城时,我无意中看了一眼后视镜,里面映出了很有意思的景象。

当时正值黄昏,大家都把车灯打着,我开车沿着一条长长的山路下到桥上来。因此,向后望去,我可以看见后面几英里的路况。我可以看见对面的那条车道上大约有5个拥堵波,而我后面的车辆呢,延绵数英里,全部是均匀的分布。我之前都没有意识到,由于我的匀速行驶,我的车把交通堵塞“吃掉”了。我前面的车都陷在走一阵停一阵的周期里,而我后面的每辆车都被迫稳在一个35英里每小时(大约56公里/时)的速度上行驶。我这小小一辆车缓解了数英里的“走一下停一下”。只一个“润滑原子”,就对汇聚众多车辆粒子的“交通管道”产生了深远的影响。

不用来回换挡、紧赶慢赶地开车是件好事,但我一直以为这样做是出于精神(即要心平气和、谦逊礼让)而非实际的考虑,但我上面的经验表明,事实并非如此。只一个与人无争、乐于让人在自己前面并道的司机,就确实可以抵消堵塞、舒解交通。而我估计反过来也一样:常规的驾驶会制造拥堵。

假设我们都争着往前开、一有空隙就变道抢位置,与前面的车之间不留一点距离,生怕有人“插我们的队”。稍有堵车迹象,就拼命加速而后刹车,给后面制造出一个巨大的拥堵波。反复加速停止,拥堵的波会越变越强。让人觉得讽刺的是,心急开快车的人可能会不知不觉“放大”他们最讨厌的拥堵波。

单个司机疏通整个拥堵

我很快就意识到,可以用同样方式来抵消小规模的堵车。大堵车只不过是一系列均匀分布的小拥堵。每当一段间距从后面过来时,一个小的拥堵就湮灭了。这样,拥堵队列的后面没有新的汽车加入,而前端的车辆又不断在离开,这些小的拥堵就会逐渐消失不见。如果拥堵足够小,而这段空间足够大,那么只要一辆车就可能消减掉整个大堵车。

我又想起来很多年前,又是一个由爱看热闹的家伙引起了车流短暂拥堵,当我的车好不容易不堵了的时候,我总是猛踩油门、使劲儿加速。我想,要是每个人都这样,就都不用减速了。但这样做一点用处都没有,因为我前面的车不会加速。我不能强迫我前面的车主猛踩油门,所以我是心有余而力不足,看能看着拥堵慢慢地“蒸发”。啊哈!我可以通过放慢速度控制我后面的车,但在我前面的就鞭长莫及了。因此,除非每辆车都一起加速,否则在堵车中开再快也没有用,而且越是这样车越堵。但如果一辆车在从后面接近拥堵时减速,就能改变所有在他后面的车的行为,从而减少附近区域本来会形成的一大片拥堵。要是这个司机计算好,在接近拥堵车流之前就与前车间留出了相当大一截距离,就可以把拥堵波“吃掉”,而拥堵也会减少。

​我晚上下班的时候一般走I-5号公路,从埃弗里特(Everett,位于西雅图以北40公里处,是波音公司的生产基地之一)往南,在出高速到林伍德(Lynnwood)匝道那段的右边那条车道上,总是有一长串汽车,车头连车尾的用2英里左右的时速在爬行。因此,我那天特意走了会堵车的右车道,并故意在前面留出一段很长很长的距离。当我遇到堵车的时候,我前面的空路大约有1000英尺(大约300米)那么长。当然,我这么做后面的车就没有办法前去增加拥堵,而本来堵在那里的车流又在前端不断消减,等我到达的时候,堵车是它平时的一半大小。真是令人震惊,我一个司机就把拥堵波抵消掉了那么大一块。

但肯定的,我的行为不仅仅是减小了拥堵。为了制造与前车之间的距离,我的平均时速大约比交通高峰时低了大约10英里/时(约合16公里/时)。我以这样的速度开了几分钟,这使得我后面的车都略微放慢了了速度。上面说了,我遇到拥堵时,其规模已经比往常小了一半。但是,拥堵波并没有消除,而是变成了一个从我开始向后蔓延的减速波。往常,汽车一般是以50英里每小时的速度驾驶,然后遇上拥堵停下来,等几分钟后再开,现在,大家都以40英里每小时的速度往前开,然后遇上一个小得多的拥堵。如果我当时再把速度调整一些,就可以疏通整个拥堵,我后面的车可以都不用停了。

经验总结

我从上述情况中总结出了一条基本的原则(现在看答案其实太简单了!):反拥堵脉冲能够抵消拥堵波。车与车之间的空隙可以缓解交通堵塞。通过放缓车速,与前面的车间逐渐拉开距离,我相当于在我的前方制造了一个“反拥堵脉冲”。当我的反拥堵脉冲最终与“拥堵波”相遇时,就像正电子撞上电子,两相湮灭。这是非线性物理学里的孤子:两个孤波消减了彼此,留下模糊的均衡。

我接着想:要是我找几个朋友来和我一起做试验,我们可以在彼此之间隔上好几英里,我们每辆车前面都可以形成一个比较大的反拥堵脉冲,而受这种连续反向脉冲的影响,大规模的堵车我们都可以疏通。在车流量比较小的时候,我们之间保持不了一段大的距离,因为要从后面超过我们很容易;但要是很多个这样开车开得慢的司机,每个人前面都有一段距离,就相对于有很多个反拥堵脉冲,这些反拥堵的力量加起来,再大规模的堵车也能瓦解。

我学到的另一个教训是,要事先做好准备,先很多很多步就计划好。我发现,当我的车被堵住时,我没办法在开出拥堵以后对车流产生影响。我希望被堵着的车能尽快减少。但这样做从来没有见效过,因为我没有办法绕过我前面慢慢开车的那个家伙。但是,如果我提前计划好,带着一段空间遭遇堵车,我就能利用这个空间来对堵塞做点什么。而一旦我跟其他人一样都被堵住了,就什么事情也做不了了。为了能影响拥堵,我必须在遇上堵车前就有所行动,而不是被困在里面之后才开始。 

西雅图在高峰时段会交通中会有许许多多个分散的拥堵,有了足够多的人(或许还有手机和GPS装置),我们可以主动疏通西雅图主干道上的拥堵!现在这还都是幻想,而且一伙人“合谋”干扰交通很可能是违法的。尽管单个司机能疏通很大一截拥堵,但有些事情是几个人联合起来怎么样也没有办法完成的。例如,我放慢行驶速度,但前面也不会出现空档,因为很快就会有其他司机从我后面擦身而过。在我的实验中,我之所以可以创造出“反拥堵”空间,只有当交通非常非常拥挤,而且只有极少数司机敢于离开他们的队列,插到我前面才行。

 

 

编辑的话:作者是“业余交通动力学家”,记述的是他实际驾车观测到的结果。絮叨了些,但对实际驾车的人而言,这样的体验难能可贵。再次强调,这样做有危险,请勿模仿。遵守交通规范,注意行车安全!

 

 

本文转自:果壳

砍掉产品80%的功能 集中力量把那20%做到八十分以上

昨天在微博上发了这么一句话:“砍掉这个产品80%的功能,集中力量把那20%做到八十分以上”。作为一名基层码农,这本是一句对某些产品状况无可奈何的吐槽,没想到收获了很多不明真相群众的赞扬、反驳以及误解。

为什么产品要做减法?

  当然,这的确是一句很没溜的话,砍掉产品功能当然不能儿戏,何况砍掉80%。而80%、20%显然也只是不准确的感性数字。那么为什么要砍掉产品功能,砍掉哪些产品功能,以及如何砍?

  个人认为,根据与用户需求、产品主旨的契合度,产品功能可以分为如下几种:

  1,核心功能:例如搜索引擎的搜索功能、IM的通信功能、电子商务网站的购物功能、门户网站的内容发布功能等等。这些功能直接满足用户需求,是产品最核心的部分。不用说,这些功能只能逐步强化精细化,绝不应该砍掉,除非产品转型;

  2,系统工具:例如社交网站的私密通信工具,电子商务网站的搜索工具、BBS的用户管理功能等。这些工具并不直接满足用户需求,但却是满足用户需求过程中必不可少的环节。这些功能有可能利用的频率并不高,例如网站黑名单功能,但却是一个成熟系统必须具备的功能。绝不可以因使用频率低而更改其主旨,更不应该砍掉;

  3,附属功能:例如QQ的QQ秀与好友印象、微信的游戏、百度的贴吧等等,这些功能满足用户的附属需求,它们附着于主需求之上。良好的附属功能是产品微创新非常重要类型,可以进一步提高用户体验;

  4,附加功能:例如搜索引擎与门户站点的广告功能,给其它产品导流功能,以及“与产品主旨无关的功能”;

  产品做减法,更多的是第四种。部分功能的附加是无奈之举,例如广告,这部分功能不是不应该砍,而是不能。能砍掉的更多的是“与产品主旨无关的功能”。那么,何谓“与产品主旨无关的功能”?为什么又要砍掉它?

  数年以前,谷歌出了一款叫做iGoogle的工具,一时风靡。这款工具上,用户可以把自己需要的功能添加到一个页面上,包括自己的邮箱、日历、天气预报、记事本等等。在这个页面上,可以只登陆一次,做很多工具的事情,非常美好,中国包括百度网易等很多公司都做了类似工具,但逐渐销声匿迹了。为什么呢?

  其实原因很简单:用户不习惯这样用系统,用户只希望在一个平台上满足自己的一个核心需求。去饭店就是去吃饭的,去电影院就是去看电影的,去图书馆就是为了借书的。正如同上百度就是为了搜索,上QQ就是为了通信,上人人就是想看看同学,从来没有一个平台能把所有用户需求都满足。

  产品主旨的选择是非此即彼的,是人人就不能再是微博,是微博就不能再是微信。同样的功能,不同的细节与呈现方式,会使得产品的主旨并不一样。人人、微博、微信都有长短内容发布功能,都能跟用户建立关系,都能看到用户的发布信息,这些功能点很类似,但是其功能的细节不同,于是它们是不同产品,用户对于它们的定位与期待是不同的。

  所以电影院不能再去添加饭店功能。当然,在电影院可以出售饮料与爆米花,因为满足的是用户“看电影时候的就餐需求”。饭店不能再去做电影院,但在饭店放一个电视往往也可以提高就餐者的体验,因为满足的是用户“就餐时的娱乐需求”。刻意的附着与悉心的附加,两者之间差之毫厘,失之千里。

  那么,是不是“附属功能”就越多越好呢?也不尽然。一个系统过多的“附属功能”,尤其是低质量“附属功能“的附着,也是一个灾难。产品功能都是消耗用户资源的,需要消耗用户的认知能力,需要让用户点击,需要消耗系统的位置。如果用户不用,或者用的太少,这些资源就白白浪费,浪费过大的时候,灾难就产生了,用户的将很难辨清产品主要功能,会看不懂系统,直接的恶果就是老用户的厌烦,新用户更是很难融入。

  总体而言,产品功能不是越多越好,不是越多就越能够给予用户更高体验。让产品承载多少附属需求与附加需求,需要良好的掌控把握。

  还有一个很重要的原因,就是研发资源的有限。

  既然产品功能消耗用户资源,那么如果产品消耗的资源不能大于给用户产生的价值,就没有意义,甚至是负分的。如果说一个八十分的产品,可以给用户创造八十分的价值,那么只有六十分的产品,可能并不能给用户创造六十分的价值,甚至不能给用户创造任何价值。