使用するときのマトリックスPreXXXとPostXXX理解のために

免責事項:この記事はブロガーオリジナル記事ですが、許可ブロガーなく再生してはなりません。https://blog.csdn.net/One_Month/article/details/89478898

カスタムビューでは、ビットマップを描画するときとき
canvas.drawBitmap(ビットマップ、マトリックス、ペイント)
マトリックスの影響を示す行列、オンラインチャートであるマトリックスを、使用する方法

各数値行列1.Matrixの効果

行列式
X軸の最初の行の効果を、それぞれ、スケール、スキュー剪断、翻訳トランススケーリングされた
第二列の最初の行に類似するY軸に影響を与える、行列乗算をパターンに適用される
インターネットからの特定のマトリックスの挙動制御、画像
回転変位によって影響される、ありますDESCRIPTIONスケーリングおよび剪断は
スケールとせん断
例スケーリング、スケールを与える
ズーム計算
点と元のデータ行列の座標、行列乗算、行ごと右側である
X = K1の* X0 + 0 *の Y0 + 0 * 1 = K1を* X0は、
X座標がK1回スケーリングされることが分かる
= 0 *のX0 + K2 * yを
Y0 + 0 * 1 = K2の*のY0は、 Yは、K2時間スケール時間を調整することがわかります

つまり、画像への影響は、ズームのための2つの位置を示します

2.前と後の基本的な違いについて言います

私は、後に遭遇し、ここで終わりにベースノート、preXXXの方法をとpostXXXはメソッド混乱
などの
翻訳
1.preTranslateを()、ソースを説明しました

   /**
     * Preconcats the matrix with the specified translation. M' = M * T(dx, dy)
     */
    public boolean preTranslate(float dx, float dy) {
        nPreTranslate(native_instance, dx, dy);
        return true;
    }
    
M' = M * T(dx, dy)
也就是原矩阵在左边,要实现平移转换的的操作在右边,也可以说是原矩阵的左乘

T(dx, dy)就是一个函数表示,表示构造一个平移矩阵
M为原矩阵,当新建一个Matrix,就是一个单位矩阵,下图就是个单位矩阵,
斜边为1,其余为0

行列

2.如果是postTranslate,源码说明

 /**
     * Postconcats the matrix with the specified translation. M' = T(dx, dy) * M
     */
    public boolean postTranslate(float dx, float dy) {
        nPostTranslate(native_instance, dx, dy);
        return true;

M' = T(dx, dy) * M
也就是原矩阵的右乘

矩阵乘法的特性是:
矩阵乘法不满足交换律,即 AB ≠ BA
矩阵乘法满足结合律,即 (AB)C = A(BC)
矩阵与单位矩阵相乘结果不变,即 A * I = A

对于左乘和右乘有什么影响,特别是多个操作结合,比如preTranslate,preScale
等等。计算起来很复杂

网上有一种说法,说的是

preXXX就是先执行,postXXX就是后执行,但是其实我们知道,代码的执行顺序
是根据你写的代码先后,preXXX和postXXX在我们调用的时候就已经执行,得到
了新的Matrix,比如执行preTranslate,preScale
M’ = M * T * S T表示preTranslate,S表示preScale
调用了M*T就已经产生新的Matrix内部结构,然后再和S操作

所以我们在用的时候我想可以这么理解

用法结论

就是在执行逻辑上,比如,我们想要先位移,再缩放,再旋转,我们想要的是执行这个结果
就可以preRotate,preScale,preTranslate,按这个顺序调用,内部公式就是
M’ = M * R * S * T
我们可以逻辑上认为越靠右边的行为越先执行,但是代码执行顺序不是如此,只是我们为了
达到目标效果,逻辑上这么想,内部经历了复杂计算对应了我们的逻辑执行顺序,
得到我们想要的Matrix,这个Matrix实现了这个逻辑顺序下的计算,但是具体内部是怎么计算
出来的,我也无法得知,也期待有喜欢研究的道友讲解

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

		//保存画布状态
        canvas!!.save()
        //重置Matrix,避免后续影响
        mMatrix.reset()
        //画布平移,將画布中心移动到屏幕中心
        canvas.translate(width/2f,height/2f)
        //先画出原图做对比
        canvas.drawBitmap(bitmap,0f,0f,null)

		//先画一个只旋转和平移的图,为了和下面的操作对比,看scale和translate谁先执行
		(逻辑上)
        mMatrix.preRotate(90f)
        mMatrix.preTranslate(100f,100f)
        canvas.drawBitmap(bitmap,mMatrix,null)
        mMatrix.reset()
        //实现我们之前说的平移,缩放,旋转的操作,按这个顺序
        mMatrix.preRotate(progress)
        mMatrix.preScale(0.5f,0.5f)
        mMatrix.preTranslate(100f,100f)

        canvas.drawBitmap(bitmap,mMatrix,null)
        canvas.restore()
    }

效果图如下
レンダリング

最右边的是原图,可以看到在屏幕中心点开始绘制
最左边的是没有缩放的
最小的是3个操作都有的

我平移了(100,100),也就是向右100,向下100(屏幕坐标系是向下为Y轴正向)

假设是先做的缩放再做的平移,那么缩放时候是在原点缩放,也就是屏幕中心,那么他的左上角还应该是(0,0),然后平移了(100,100),左上角旋转后现在最终视觉上成了右上角,
那么右上角坐标现在应该是(-100,100)

但是我们看到只做了旋转和平移的那张图,也就是最左边的,他明显更加远离原点,说明他的位置才是(-100,100)
所以就说明最小的那张图先做了平移操作,坐标变成(100,100),旋转后变成(-100,100),最后坐了缩放,缩放是根据原点缩放,所以那个点缩放了一般变成了(-50,50),所以就是我们说的顺序

再做个实验,如果我们最后一步是postTranslate,能不能达到我们逻辑上的最后做平移呢

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
//        canvas!!.drawBitmap(bitmap,Rect(0,0,(bitmap.width*progress).toInt() ,bitmap.height),
//                RectF(0f,0f,bitmap.width*progress,bitmap.height.toFloat()), Paint())

//        canvas!!.drawBitmap(bitmap,0f,0f,null)
//        canvas.translate(0f,bitmap.height.toFloat()+200f)
        canvas!!.save()
        mMatrix.reset()
        canvas.translate(width/2f,height/2f)
        canvas.drawBitmap(bitmap,0f,0f,null)

        mMatrix.preRotate(progress)
        mMatrix.preTranslate(100f,100f)
        canvas.drawBitmap(bitmap,mMatrix,null)
        mMatrix.reset()
        mMatrix.preRotate(progress)
        mMatrix.preScale(0.5f,0.5f)
        //改成postTranslate,之前是preTranslate
        mMatrix.postTranslate(100f,100f)

        canvas.drawBitmap(bitmap,mMatrix,null)
        canvas.restore()
    }
    这样公式就变成
    M' = T * M * R * S

レンダリングの外観
レンダリング
左上及び移動距離の原点を見ることができ
、その後、元に図中左から右上隅を見て、それらの間の距離と同じ、画像が最初に経験したことを示す
スケールをそのまま座標の原点は、右下に移動します100、100は、また、上記のことが証明された
アプローチが可能です。

再びそれを言います

コードの実行の順序があれば、事前と事後に従ったものではなく、実行する必要がありますが、私たちは何をしたい
、我々は彼が効果ロジックを実現しましょう、あなたはの使用の合理化する方法を考えるために、上記の指示に従うことができます
各缶、事前と事後式が書き出され、その後、式を見て右から左に、最終結果を見ては、
一貫性があり、憶測ではありません。

反例がある場合は、あなたに感謝し、私に修正する機会を与え、私にメッセージを与えることを歓迎

参考記事:
カスタムビュー高度な-マトリックス原則

このリファレンスの記事ブログのシリーズである、あなたが見ることができる、カスタムビューたくさんのことを学ぶことができます

おすすめ

転載: blog.csdn.net/One_Month/article/details/89478898