数学的观点:向量空间和仿射空间(转)

From:  http://www.cnblogs.com/CoolJie/archive/2011/07/12/2104282.html

在计算机图形学中,各种抽象空间是非常重要的,理清楚这些空间,对于计算机图形学的理解将会大有益处。

. 标量集合(scalar aggregates):

标量集合中的任何两个标量都可以经过加法和乘法这两种运算得到另一个标量。如果这两种运算满足封闭性、结合律、交换律和对逆元素的要求,那么这些标量就构成了一个标量场。我们熟悉的标量有实数、复数和有理函数等。

. 线性空间(向量空间Vector space)

  它也许是最重要的数学空间。向量空间中包含了两种不同的实体---向量和标量。除了两个标量之间的运算外,向量空间中还定义了标量---向量乘法和向量---向量加法,前者由一个标量和一个向量得出另一个向量,后者由两个向量得出另一个向量

三. 额外结构

研究向量空间很自然涉及一些额外结构。额外结构如下:

一个实数或复数向量空间加上长度概念。就是范数称为赋范向量空间(normed linear space)

在数学上,我们知道,一个集合(向量),通过一种映射关系(矩阵),可以得到另外一个几何(另外一个向量)。
那么向量的范数,就是表示这个原有集合的大小。而矩阵的范数,就是表示这个变化过程的大小的一个度量。 

       常用范数

这里以Cn空间为例,Rn空间类似。
最常用的范数就是p-范数。若
,那么
可以验证p-范数确实满足范数的定义。其中三角不等式的证明不是平凡的,这个结论通常称为闵可夫斯基(Minkowski)不等式。
当p取0,1,2,∞的时候分别是以下几种最简单的情形:
0范数,向量中非零元素的个数。
      1-范数( 为绝对值之和。 ):║x║1=│x 1 │+│x 2 │+…+│x n
2-范数( 通常意义上的模,距离 ):║x║2=(│x 1 2 +│x 2 2 +…+│x n 2 1/2
∞-范数(取向量的最大值):║x║∞=max(│x1│,│x2│,…,│xn│)
一个实数或复数向量空间加上长度和角度的概念,称为 内积空间 (inner product space)

内积空间有时也叫做准希尔伯特空间,因为由内积定义的距离完备化之后就会得到一个希尔伯特空间(Hilbert space)。
在早期的著作中,内积空间被称作酉空间,但这个词现在已经被淘汰了。在将内积空间称为酉空间的著作中,“内积空间”常指任意维(可数/不可数)的欧几里德空间Euclidean Space)。

一个向量空间加上拓扑学符合运算的(加法及标量乘法是连续映射)称为拓扑向量空间(Topological space0

一个向量空间加上双线性算子(定义为向量乘法)是个域代数。

仿射空间:

  它是向量空间的扩展,除了标量和向量外,它还包含了另外一种对象---点。尽管在仿射空间中队两个点以及一个标量没有定义运算,但对一个向量和一个点定义了一种运算---向量-点加法,它的结果是一个点。也可以说有一种称为点---点减法的运算,这种运算由两个点得到一个向量。

或者可以这样理解:仿射空间是假设我们已经定义好了向量空间,然后定义一个点的集合,同时规定了点和向量之间的求和运算(加和的结果仍是搜索点),这个点集就是这个向量空间相伴的仿射空间。


从基本数学概念上来说, 一个坐标系对应了一个仿射空间 (Affine Space) , 当矢量从一个坐标系变换到另一个坐标系时要进行线性变换 (Linear Transformation). 对点来说, 要进行仿射变换 (Affine Transformation). 这就是我们利用同源坐标的理由. 它能在对矢量进行线性变换的同时对点进行仿射变换. 坐标变换的基本操作就是将变换矩阵乘以矢量或点.



  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设有两组空间数据,分别为点集 $A$ 和点集 $B$,其中点集 $A$ 经过了某个仿射变换 $T$ 后得到了点集 $B$,现在需要求解仿射变换参数。 我们可以将点集 $A$ 和点集 $B$ 中的每个点看作一个向量,然后通过最小二乘法求解仿射变换参数。 具体地,我们可以将仿射变换 $T$ 表示为以下形式: $$ T = \begin{bmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \end{bmatrix} $$ 其中 $a,b,c,d,e,f$ 是待求解的参数。 对于每个点 $(x_i,y_i)$,它在经过仿射变换 $T$ 后的坐标为: $$ \begin{bmatrix} x'_i \\ y'_i \\ 1 \end{bmatrix} = T \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} $$ 令 $p_i = (x_i,y_i)$,$q_i = (x'_i,y'_i)$,则上式可以写成: $$ \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \begin{bmatrix} a & b \\ d & e \end{bmatrix} \begin{bmatrix} x_i \\ y_i \end{bmatrix} + \begin{bmatrix} c \\ f \end{bmatrix} $$ 将所有点的坐标代入上式得到: $$ \begin{bmatrix} x'_1 & y'_1 & 1 & 0 & 0 & 0 \\ x'_2 & y'_2 & 1 & 0 & 0 & 0 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ x'_n & y'_n & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & x'_1 & y'_1 & 1 \\ 0 & 0 & 0 & x'_2 & y'_2 & 1 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ 0 & 0 & 0 & x'_n & y'_n & 1 \\ \end{bmatrix} \begin{bmatrix} a \\ b \\ c \\ d \\ e \\ f \end{bmatrix} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \\ y_1 \\ y_2 \\ \vdots \\ y_n \end{bmatrix} $$ 设左边的矩阵为 $A$,右边的向量为 $b$,则仿射变换参数可以通过求解以下最小二乘问题得到: $$ \min_{x} \|Ax-b\|^2 $$ 其中 $\|\cdot\|$ 表示欧几里得范数。 可以使用奇异值分解(SVD)方法求解上述最小二乘问题。 以下是求解仿射变换参数的 C++ 代码示例: ```cpp #include <iostream> #include <vector> #include <Eigen/Core> #include <Eigen/Dense> using namespace std; using namespace Eigen; // 求解仿射变换参数 bool solveAffineTransform(const vector<Vector2d>& A, const vector<Vector2d>& B, Matrix3d& T) { const int n = A.size(); if (B.size() != n || n < 3) { return false; } // 构造最小二乘问题的矩阵 A 和向量 b MatrixXd A_mat(2 * n, 6); VectorXd b_vec(2 * n); for (int i = 0; i < n; ++i) { const double x = A[i](0); const double y = A[i](1); const double x_ = B[i](0); const double y_ = B[i](1); A_mat.row(i) << x, y, 1, 0, 0, 0; A_mat.row(i + n) << 0, 0, 0, x, y, 1; b_vec(i) = x_; b_vec(i + n) = y_; } // 使用奇异值分解求解最小二乘问题 JacobiSVD<MatrixXd> svd(A_mat, ComputeThinU | ComputeThinV); const VectorXd x = svd.solve(b_vec); // 将参数化为仿射变换矩阵 T << x(0), x(1), x(2), x(3), x(4), x(5), 0, 0, 1; return true; } int main() { // 示例数据 vector<Vector2d> A = { Vector2d(0, 0), Vector2d(1, 0), Vector2d(0, 1) }; vector<Vector2d> B = { Vector2d(1, 2), Vector2d(2, 2), Vector2d(1, 3) }; Matrix3d T; if (solveAffineTransform(A, B, T)) { cout << "Affine transform matrix:\n" << T << endl; } else { cout << "Failed to solve affine transform." << endl; } return 0; } ``` 注意,上述代码中使用了 Eigen 库进行矩阵运算。如果你没有安装 Eigen 库,则需要先下载并安装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值