跳转至

矩阵的基本运算以及常见仿射变换

矩阵基本运算

矩阵基本运算包括矩阵的加法、减法、数乘、乘法和转置等。以下分别介绍这些运算的规则和方法。

1. 矩阵的加法

两个矩阵相加,要求它们的行数和列数相同。结果矩阵的每个元素是对应位置的元素相加得到的。

设矩阵 \(A\) 和矩阵 \(B\) 分别为:

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix}, \quad B = \begin{pmatrix} b_{11} & b_{12} \\ b_{21} & b_{22} \end{pmatrix} \]

则矩阵 \(A + B\) 为:

\[ A + B = \begin{pmatrix} a_{11} + b_{11} & a_{12} + b_{12} \\ a_{21} + b_{21} & a_{22} + b_{22} \end{pmatrix} \]

2. 矩阵的减法

两个矩阵相减,要求它们的行数和列数相同。结果矩阵的每个元素是对应位置的元素相减得到的。

设矩阵 \(A\) 和矩阵 \(B\) 分别为:

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix}, \quad B = \begin{pmatrix} b_{11} & b_{12} \\ b_{21} & b_{22} \end{pmatrix} \]

则矩阵 \(A - B\) 为:

\[ A - B = \begin{pmatrix} a_{11} - b_{11} & a_{12} - b_{12} \\ a_{21} - b_{21} & a_{22} - b_{22} \end{pmatrix} \]

3. 矩阵的数乘

一个数乘以一个矩阵,结果矩阵的每个元素是原矩阵对应元素乘以这个数得到的。

设矩阵 \(A\) 为:

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix} \]

\(k\) 为一个标量,则 \(kA\) 为:

\[ kA = \begin{pmatrix} k \cdot a_{11} & k \cdot a_{12} \\ k \cdot a_{21} & k \cdot a_{22} \end{pmatrix} \]

4. 矩阵的乘法

两个矩阵相乘,要求第一个矩阵的列数等于第二个矩阵的行数。结果矩阵的第 \(i\) 行第 \(j\) 列的元素是第一个矩阵的第 \(i\) 行与第二个矩阵的第 \(j\) 列的点积。

设矩阵 \(A\) 和矩阵 \(B\) 分别为:

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix}, \quad B = \begin{pmatrix} b_{11} & b_{12} \\ b_{21} & b_{22} \end{pmatrix} \]

则矩阵 \(AB\) 为:

\[ AB = \begin{pmatrix} a_{11}b_{11} + a_{12}b_{21} & a_{11}b_{12} + a_{12}b_{22} \\ a_{21}b_{11} + a_{22}b_{21} & a_{21}b_{12} + a_{22}b_{22} \end{pmatrix} \]

5. 矩阵的转置

一个矩阵的转置是将原矩阵的行和列互换得到的矩阵。

设矩阵 \(A\) 为:

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix} \]

则矩阵 \(A\) 的转置 \(A^T\) 为:

\[ A^T = \begin{pmatrix} a_{11} & a_{21} \\ a_{12} & a_{22} \end{pmatrix} \]

仿射变换

仿射变换是几何图形处理中非常重要的工具,它包括线性变换(如旋转、缩放、剪切)和平移。以下列出了一些常见的仿射变换及其矩阵表示。

1. 平移

  • 二维平移:将点\((x, y)\)沿向量\((a, b)\)平移可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} 1 & 0 & a \\ 0 & 1 & b \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} \]
  • 三维平移:将点\((x, y, z)\)沿向量\((a, b, c)\)平移可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ z' \\ 1 \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & a \\ 0 & 1 & 0 & b \\ 0 & 0 & 1 & c \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} \]

2. 旋转

  • 二维旋转:将点\((x, y)\)绕原点旋转角度\(\theta\)可以表示为:
\[ \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} \]
  • 三维旋转:将点\((x, y, z)\)\(z\)轴旋转角度\(\theta\)可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ z' \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} \]

3. 缩放

  • 二维缩放:将点\((x, y)\)\(x\)轴和\(y\)轴方向上分别缩放\(a\)\(b\)倍可以表示为:
\[ \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} a & 0 \\ 0 & b \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} \]
  • 三维缩放:将点\((x, y, z)\)\(x\)轴、\(y\)轴和\(z\)轴方向上分别缩放\(a\)\(b\)\(c\)倍可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ z' \end{pmatrix} = \begin{pmatrix} a & 0 & 0 \\ 0 & b & 0 \\ 0 & 0 & c \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} \]

4. 剪切

  • 二维剪切:将点\((x, y)\)\(x\)轴方向上剪切\(k\)倍可以表示为:
\[ \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & k \\ 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} \]
  • 三维剪切:将点\((x, y, z)\)\(x\)轴方向上剪切\(k\)倍可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ z' \end{pmatrix} = \begin{pmatrix} 1 & k & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} \]

5. 反射

  • 二维反射:将点\((x, y)\)关于\(x\)轴反射可以表示为:
\[ \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} \]
  • 三维反射:将点\((x, y, z)\)关于\(xy\)平面反射可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ z' \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & -1 \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} \]

6. 组合变换

  • 组合变换:仿射变换可以组合使用,例如先旋转后平移,可以表示为:
\[ \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} 1 & 0 & a \\ 0 & 1 & b \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} \]

C#代码实现

1. 定义矩阵类

using System;

public class Matrix
{
    public double[,] Data { get; private set; }
    public int Rows { get; private set; }
    public int Columns { get; private set; }

    public Matrix(int rows, int columns)
    {
        Rows = rows;
        Columns = columns;
        Data = new double[rows, columns];
    }

    public Matrix(double[,] data)
    {
        Rows = data.GetLength(0);
        Columns = data.GetLength(1);
        Data = data;
    }

    // 矩阵加法
    public static Matrix operator +(Matrix a, Matrix b)
    {
        if (a.Rows != b.Rows || a.Columns != b.Columns)
            throw new ArgumentException("Matrices dimensions must match.");

        var result = new Matrix(a.Rows, a.Columns);
        for (int i = 0; i < a.Rows; i++)
        {
            for (int j = 0; j < a.Columns; j++)
            {
                result.Data[i, j] = a.Data[i, j] + b.Data[i, j];
            }
        }
        return result;
    }

    // 矩阵减法
    public static Matrix operator -(Matrix a, Matrix b)
    {
        if (a.Rows != b.Rows || a.Columns != b.Columns)
            throw new ArgumentException("Matrices dimensions must match.");

        var result = new Matrix(a.Rows, a.Columns);
        for (int i = 0; i < a.Rows; i++)
        {
            for (int j = 0; j < a.Columns; j++)
            {
                result.Data[i, j] = a.Data[i, j] - b.Data[i, j];
            }
        }
        return result;
    }

    // 矩阵乘法
    public static Matrix operator *(Matrix a, Matrix b)
    {
        if (a.Columns != b.Rows)
            throw new ArgumentException("Number of columns in the first matrix must match the number of rows in the second matrix.");

        var result = new Matrix(a.Rows, b.Columns);
        for (int i = 0; i < a.Rows; i++)
        {
            for (int j = 0; j < b.Columns; j++)
            {
                result.Data[i, j] = 0;
                for (int k = 0; k < a.Columns; k++)
                {
                    result.Data[i, j] += a.Data[i, k] * b.Data[k, j];
                }
            }
        }
        return result;
    }

    // 矩阵转置
    public Matrix Transpose()
    {
        var result = new Matrix(Columns, Rows);
        for (int i = 0; i < Rows; i++)
        {
            for (int j = 0; j < Columns; j++)
            {
                result.Data[j, i] = Data[i, j];
            }
        }
        return result;
    }

    // 打印矩阵
    public override string ToString()
    {
        var result = "";
        for (int i = 0; i < Rows; i++)
        {
            for (int j = 0; j < Columns; j++)
            {
                result += Data[i, j] + "\t";
            }
            result += "\n";
        }
        return result;
    }
}

2. 实现仿射变换

public class AffineTransformations
{
    // 平移矩阵
    public static Matrix TranslationMatrix(double tx, double ty)
    {
        return new Matrix(new double[,]
        {
            {1, 0, tx},
            {0, 1, ty},
            {0, 0, 1}
        });
    }

    // 旋转矩阵(二维)
    public static Matrix RotationMatrix(double angle)
    {
        double rad = angle * Math.PI / 180.0;
        return new Matrix(new double[,]
        {
            {Math.Cos(rad), -Math.Sin(rad), 0},
            {Math.Sin(rad), Math.Cos(rad), 0},
            {0, 0, 1}
        });
    }

    // 缩放矩阵
    public static Matrix ScalingMatrix(double sx, double sy)
    {
        return new Matrix(new double[,]
        {
            {sx, 0, 0},
            {0, sy, 0},
            {0, 0, 1}
        });
    }

    // 剪切矩阵(沿x轴)
    public static Matrix ShearMatrix(double shx)
    {
        return new Matrix(new double[,]
        {
            {1, shx, 0},
            {0, 1, 0},
            {0, 0, 1}
        });
    }

    // 反射矩阵(沿x轴)
    public static Matrix ReflectionMatrix()
    {
        return new Matrix(new double[,]
        {
            {1, 0, 0},
            {0, -1, 0},
            {0, 0, 1}
        });
    }

    // 应用仿射变换
    public static Matrix ApplyTransformation(Matrix point, Matrix transformation)
    {
        return transformation * point;
    }
}

3. 测试代码

class Program
{
    static void Main(string[] args)
    {
        // 定义一个点 (2, 3)
        var point = new Matrix(new double[,]
        {
            {2},
            {3},
            {1}
        });

        // 平移矩阵
        var translation = AffineTransformations.TranslationMatrix(4, 5);
        var translatedPoint = AffineTransformations.ApplyTransformation(point, translation);
        Console.WriteLine("平移后: ");
        Console.WriteLine(translatedPoint);

        // 旋转矩阵
        var rotation = AffineTransformations.RotationMatrix(45); // 45度
        var rotatedPoint = AffineTransformations.ApplyTransformation(point, rotation);
        Console.WriteLine("旋转后: ");
        Console.WriteLine(rotatedPoint);

        // 缩放矩阵
        var scaling = AffineTransformations.ScalingMatrix(2, 3);
        var scaledPoint = AffineTransformations.ApplyTransformation(point, scaling);
        Console.WriteLine("缩放后: ");
        Console.WriteLine(scaledPoint);

        // 剪切矩阵
        var shear = AffineTransformations.ShearMatrix(0.5);
        var shearedPoint = AffineTransformations.ApplyTransformation(point, shear);
        Console.WriteLine("剪切后: ");
        Console.WriteLine(shearedPoint);

        // 反射矩阵
        var reflection = AffineTransformations.ReflectionMatrix();
        var reflectedPoint = AffineTransformations.ApplyTransformation(point, reflection);
        Console.WriteLine("反射后: ");
        Console.WriteLine(reflectedPoint);
    }
}

评论