上篇我们把矩阵的乘法和转换点等基础变换实现好了(个人觉得转换点也不算很基础的东西),现在我们来把应用型的功能,也就是标题所指的功能给实现出来。
在我最熟悉的AS3里面,Adobe为了降低使用门槛,把这些方法直接实现到矩阵类中,而我则是打算单独做个工具类来封装这些方法,名为MatrixUtil。
function MatrixUtil() {
}
然后,我们把这几种变换的矩阵逐一列出来并进行实现。
首先是平移
为了提高可读性,我把最后一行灰掉了,然后6个参数的顺序照着矩阵自上而下从左到右排列。
然后,作为工具类,这些方法应该以静态成员的形式存在。此处我给出生成平移矩阵,以及对已有矩阵进行平移的方法,具体如下。
MatrixUtil.getTranslateMatrix = function(tx, ty) {
return new Matrix(1, 0, 0, 1, tx, ty);
}
/**
* 平移
*
**/
MatrixUtil.translate = function(matrix, tx, ty) {
matrix.append(MatrixUtil.getTranslateMatrix(tx, ty));
}
跟上篇文章不同的是,静态成员要求不用实例化也能使用,所以不应放到function MatrixUtil函数体内,否则就得实例化才能用。
您会发现,translate方法的性能较差,不仅创建了个新对象,还做了很多次不必要的四则运算,但为了体现矩阵的通用性,此处牺牲一下效率,在性能要求较高的应用中,大家可以进行优化。
类似地,缩放是这个样子:
MatrixUtil.getScaleMatrix = function(scaleX, scaleY) {
return new Matrix(scaleX, 0, 0, scaleY);
}
/**
* 缩放
*
**/
MatrixUtil.scale = function(matrix, scaleX, scaleY) {
matrix.append(MatrixUtil.getScaleMatrix(scaleX, scaleY));
}
旋转:
MatrixUtil.getRotateMatrix = function(rotation) {
var cos = Math.cos(rotation);
var sin = Math.sin(rotation);
return new Matrix(cos, sin, -sin, cos);
}
/**
* 旋转
*
**/
MatrixUtil.rotate = function(matrix, rotation) {
matrix.append(MatrixUtil.getRotateMatrix(rotation));
}
封装好这些方法之后,我们就可以通过变换组合的形式实现各种变换了。本打算这里就演示一个图形变换的小例子,然后下篇就来实现45度地图。但写到这里的时候,我心里突然有种失落感,因为我这是在重复造轮子,没有任何实际意义。
我在三维家讲课的时候也曾经提到这一点,并且告诉他们说,不要反对重复造轮子,因为造轮子本身就是个很不错的学习过程。所以,只要你造的这个轮子不是你要发布的产品,而仅仅是你的练手之作那就没有任何毛病了。当然了,还是有很多人会认为,练手只是学生时期做的事情,出来工作了,也都是用到什么临时学什么,并且不会去做太多算法层面上的开发。
我想说的是,这往往就是很多程序员只能吃青春饭,年纪大了必须转型的一个重要原因。如果您很喜欢程序这一行(我知道这个假设对于大多数人来说并不成立),并且想一直靠这技能来赚更多的钱,抛开个人能力,学习成本,生活压力等因素(其实我知道大多数人是抛不开的),深挖一下程序底层,向史诗级进军绝对是您的不二之选。
上一段,括号里的话相信是大家关注的重点。在此我郑重地告诉大家,只要您来三维家,那括号里面的话都是浮云了,我们这儿还缺100多号开发工程师,等着你来哟~
废话完了,下篇见~88