标签:
二维图形变换的矩阵如下:
|ScaleX SkewX TransX|
|SkewY ScaleY TransY|
|Persp0 Persp1 Persp2|
ScaleX:x方向缩放倍率
ScaleY:y方向缩放倍率
TransX:x方向平移值
TransY:y方向平移值
SkewX:x方向错切值
SkewY:y方向错切值
Persp:齐次坐标的值,一般取值0或1。
graphics包中的Matrix类的方法调用native计算,jni调用了skia库中SkMatrix.cpp文件下的函数计算,各个函数实际上都是在对二维变换矩阵进行赋值:
void SkMatrix::setScale(SkScalar sx, SkScalar sy) {
if (1 == sx && 1 == sy) {
this->reset();
} else {
fMat[kMScaleX] = sx;
fMat[kMScaleY] = sy;
fMat[kMPersp2] = 1;
fMat[kMTransX] = fMat[kMTransY] =
fMat[kMSkewX] = fMat[kMSkewY] =
fMat[kMPersp0] = fMat[kMPersp1] = 0;
this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
}
}
这是以原点为中心进行缩放的矩阵赋值。
void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
if (1 == sx && 1 == sy) {
this->reset();
} else {
fMat[kMScaleX] = sx;
fMat[kMScaleY] = sy;
fMat[kMTransX] = px - sx * px;
fMat[kMTransY] = py - sy * py;
fMat[kMPersp2] = 1;
fMat[kMSkewX] = fMat[kMSkewY] =
fMat[kMPersp0] = fMat[kMPersp1] = 0;
this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask);
}
}
这是以指定坐标(px, py)为中心点进行缩放的矩阵赋值。与上一个函数对比可以发现,不仅进行了缩放还进行了平移,所以才可以表现为在指定点处缩放。
void SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
if (!dx && !dy) {
return;
}
if (this->hasPerspective()) {
SkMatrix m;
m.setTranslate(dx, dy);
this->preConcat(m);
} else {
fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy);
fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy);
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
}
}
void SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {
if (!dx && !dy) {
return;
}
if (this->hasPerspective()) {
SkMatrix m;
m.setTranslate(dx, dy);
this->postConcat(m);
} else {
fMat[kMTransX] += dx;
fMat[kMTransY] += dy;
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
}
}
static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
return a * b + c * d;
}
上面的这三个函数说明了pre和post的区别,假如有如下操作:
(1)
Matrix.scale(0.5, 0.5);
Matrix.preTranslate(100, 100);
(2)
Matrix.scale(0.5, 0.5);
Matrix.postTranslate(100, 100);
第一段代码会平移(100*0.5, 100*0.5),第二段代码会平移(100, 100),post不受之前的矩阵变换的影响。
其它函数的pre和post的意思都是如此。
另外:
scale缩放取值为-1时可以得到镜像矩阵
protected static Matrix getHorizontalMatrix(float width) {
Matrix flipHorizontalMatrix = new Matrix();
flipHorizontalMatrix.setScale(-1, 1);
flipHorizontalMatrix.postTranslate(width, 0);
return flipHorizontalMatrix;
}
上面的矩阵表示对原图进行水平镜像变换。
标签:
原文地址:http://www.cnblogs.com/fordreamxin/p/4721497.html