码迷,mamicode.com
首页 > 其他好文 > 详细

graphics包Matrix类函数理解

时间:2015-08-11 17:47:49      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

二维图形变换的矩阵如下:

|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;
    }

 上面的矩阵表示对原图进行水平镜像变换。

graphics包Matrix类函数理解

标签:

原文地址:http://www.cnblogs.com/fordreamxin/p/4721497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!