智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...

导航

Point类计算矢量

Posted on 2009-11-20 09:24  Bill Yuan  阅读(514)  评论(0编辑  收藏  举报
当要运算两点距离时,我见不少人都是用最原始的运算方法,其实2.0开始就有了Point类,可以计算两点间距离,除此之外,Point类还可用于计算矢量,某些看似复杂的计算,用上Point类就会变得简单。当然,要巧用Point类,必需要有矢量的知识。虽然,3.0的Point类和2.0的区别不大,但我之所以把这帖放在as3讨论区,是因为as3的Point类广泛地被其他类应用。最明显的是globalToLocal和localToGlobal这两个方法,2.0这两个方法的参数和返回值都是Object,但3.0都变为Point类了,使得Point类的应用更名正言顺了。

废话少说,言归正转,首先我们看看Point类的属性:
x:Number——该点的水平坐标
y:Number——该点的垂直坐标
length:Number——从(0,0)到此点的线段长度(只读属性)
从length属性我们可以看到,实际上一个Point类的实例是一个以(0,0)为始点,以(x,y)为终点的矢量,因此,我们可以应用Point类进行一些简单的矢量运算。
现在我们看看Point类给我们提供什么有用的方法:

distance(pt1:Point, pt2:Point):Number——返回 pt1pt2 之间的距离。
这个就是大家傻傻地用Math.sqart()写一长串代码计算出来的两点间距离了。

add(v:Point):Point——将另一个点的坐标添加到此点的坐标以创建一个新点。
还记得矢量相加的几何意义吗?
设a、b为矢量,则a+b=c,图中矢量c就是矢量a加矢量b的结果。
这个用来计算合力最方便。我们可以把物体的重心放到(0,0)点上,然后可以利用Point类的add方法简单计算各种力的合力。你可能会提出一个问题:如何把力转换成点的坐标呢?下面这个方法可以帮你解决这个问题。

polar(len:Number, angle:Number):Point——将一对极坐标转换为笛卡尔点坐标。
学过物理力学的人都知道,力是有大小有方向的矢量,而这个方法正好提供了把力转换成点坐标的方法。len就是力的大小,angle就是力角度。转换后计算合力,得出合力的坐标点,再读取这点的length属性,就可得到合力的大小,再利用Math.atan2(y,x)计算力的方向。多简单的运算!

offset(dx:Number, dy:Number):void——按指定量偏移 Point 对象。dx 的值将添加到 x 的原始值中以创建新的 x 值。 dy 的值将添加到 y 的原始值中以创建新的 y 值。这个要和add区分开来,因为offset是直接把值加到x、y值上。

subtract(v:Point):Point——从此点的坐标中减去另一个点的坐标以创建一个新点。
既然有了加法,当然有减法了。看看矢量的减法意义:
设a、b为矢量,则b-a=c,图中矢量c就是矢量b减去矢量a的结果。
用这个运算,你可以方便地只用一个Point类实例来记录某两点间的距离和斜率。在某些场合,这个很有用。例如当需要计算和记录某点集合里各点与其他点之间的关系时,如果分别运算距离和角度,你得用两个一一对应的数组记录,当然也可以用一个多联数组,但绝对比不上用一个Point类实例组成的一维数组简单得多,如果要对这些结果进行比较或者有下一步运算时,用这种方法更显优势。

interpolate(pt1:Point, pt2:Point, f:Number):Point——确定两个指定点之间的点。参数 f 确定新的内插点相对于参数 pt1pt2 指定的两个端点所处的位置。参数 f 的值越接近 1.0,则内插点就越接近第一个点(参数 pt1)。参数 f 的值越接近 0,则内插点就越接近第二个点(参数 pt2)。
这个方法更了不起。因为它能帮我们确定两点之间的一点,只要我们知道这点在线段中位置。实际上f是一个比例值,
f=待定点到pt2的距离/整条线段的长度
这个用来计算一些已知比例关系的点很方便。例如求地图上的某点在实际场景上的点坐标,我们只需选取一段过这点的线段,计算出f,就可以代入实际场景中对应线段,求出对应的点。

normalize(thickness:Number):void——将 (0,0) 和当前点之间的线段缩放为设定的长度。
这个实际上就是设置矢量的大小的方法。得到的结果是矢量的大小变为设定值,x、y值改变了,但是矢量的方向不变。

从Point类的属性和方法看,Point类实际上是一个彻头彻尾的矢量类,它几乎包含了所有关于矢量的基本运算。所以,要计算矢量,应优先考虑使用Point类。

PS:顺带说说globalToLocal和localToGlobal,这两个方法在as3里是DisplayObject的方法,它们可以方便地随意地转换不同显示对象中的相对坐标,它的参数和返回值都是Point类实例,所以在as3里应用Point类计算点与点间的关系,更具优势。例如mc1中有一点p1(x1,y1),mc2中有一点p2(x2,y2),如果mc1和mc2的关系很复杂,要求p1到p2的距离,如果不用这两个方法,这个运算就很复杂,用上它们就简单得多了,所求的距离d=Point.distance(p2,mc2.globalToLocal(mc1.localToGlobal(p1)));