矩阵变换; 概念和理论,是否有实际学习任何免费资源? [关闭](Matrix transfor

2019-07-29 00:32发布

我一直有乐趣绘制图表和图形的坐标最近,我通过使用矩阵变换统筹空格迷住了。

我已经能够成功地扩展和反转2维坐标空间,但现在我的胃口被激起。 :)

我在哪里可以去清晰,内容翔实,(免费),教育上的矩阵材料,矩阵数学,特别是适用于2和3维空间?

Answer 1:

原来的答案:我不知道你是否会喜欢怎样的数学课程通常会引入矩阵。 作为一个程序员,你可能与抓什么像样的3D图形的书快乐。 这当然应该有非常具体的3x3矩阵。 还发现,将教你的那些射影变换 (射影几何低维几何的一个非常美丽的地区和易于编程)。

迷你课程矩阵数学与Python 3

内容:

  1. 矩阵 [Vector, __add__, reflect_y, rotate, dilate, transform]
  2. 矩阵:重载 [Matrix, __add__, __str__, __mul__, zero, det, inv, __pow__]
  3. 奖励:复数
  4. 矩阵:将(R)进化 。 它已经在酝酿(还有在最后的总结)

前言:根据我的教学经验,我觉得被别人引用的课程是非常好的课程 。 这意味着,如果你的目标是理解矩阵作为数学家做的,比你应该通过各种手段获得的全过程。 但如果你的目标更为温和,这是我的东西,以您的需求更有针对性的尝试(但传达许多理论概念,那种矛盾的我原来的建议目标仍然写的。)

如何使用:

  • 这篇文章很长。 你可能会考虑这个印刷和怠工,如一日的一部分。
  • 代码是必不可少的。 这是程序员的一门课程。 练习是必不可少的了。
  • 你应该看看代码同伴里面包含了所有的代码以及更多
  • 这是“2 1的价格”特殊:你也可以学习Python 3在这里。 和复数。
  • 我会高度重视任何尝试读取这个(我正式晋级后最长有史以来?),可以随意发表评论,如果你不明白的地方(也如果你这样做)。

1.矩阵

矢量

之前矩阵来载体。 你肯定知道如何处理了2个和3维向量:

class Vector:
    """This will be a simple 2-dimensional vector.

    In case you never encountered Python before, this string is a
    comment I can put on the definition of the class or any function.
    It's just one of many cool features of Python, so learn it here!

    """

    def __init__(self, x, y): 
        self.x = x
        self.y = y

现在你可以写

v = Vector(5, 3)
w = Vector(7, -1)

但它没有多少乐趣本身。 让我们添加更多有用的方法:

    def __str__(self: 'vector') -> 'readable form of vector':
        return '({0}, {1})'.format(self.x, self.y)

    def __add__(self:'vector', v: 'another vector') -> 'their sum':
        return Vector(self.x + v.x, self.y + v.y)

    def __mul__(self:'vector', number: 'a real number') -> 'vector':
        '''Multiplies the vector by a number'''
        return Vector(self.x * number, self.y * number)

这使事情变得更加有趣,因为我们现在可以这样写:

print(v + w * 2)

和得到的答案(19, 1)很好地印刷作为载体(如果实施例面生,认为这代码看起来如何在C ++)。

转换

现在,这一切都冷却到能写1274 * w ,但你需要的图形更向量运算。 下面是其中一些:您可以翻转的矢量围绕(0,0)点,可以反映出其周围xy轴,可以顺时针或逆时针旋转它(这是一个好主意,在这里画的图片)。

让我们做一些简单的操作:

    ...

    def flip(self:'vector') -> 'vector flipped around 0':
        return Vector(-self.x, -self.y)

    def reflect_x(self:'vector') -> 'vector reflected around x axis':
        return Vector(self.x, -self.y)


print(v.flip(), v.reflect_x())
  • 问:是否有可能表达flip(...)使用我在下面有操作? 什么reflect_x

现在你可能想知道为什么我省略reflect_y 。 嗯,这是因为我希望你停止了片刻,写你自己的版本。 好吧,这里是我的:

    def reflect_y(self:'vector') -> 'vector reflected around y axis':
        return self.flip().reflect_x()

见,如果你看看这个函数是如何计算的,它实际上是相当琐碎。 但突然一个惊人的事情发生了:我能写只用现有的转换转换flipreflect_x 。 我都不在乎, reflect_y可以在派生类中定义没有获得xy ,它仍然能工作!

数学家会调用这些函数运算符 。 他们会说, reflect_y是通过运营商的组合物获得运营商flipreflect_x这是由表示reflect_y = flip ○ reflect_x (你应该看到的小圆圈,一个Unicode符号25CB )。

  • 注:我会很自由地使用=符号从现在开始,以表示两个操作产生相同的结果,如上面的段落。 这是一个“数学= ”,它不能被表示为程序 。

所以,如果我做

print(v.reflect_y())

我得到的结果(-5, 3) 去想象吧!

  • 问:考虑一个组成reflect_y ◦ reflect_y 。 你将如何命名?

旋转

这些操作是好的和有用的,但你可能想知道为什么我介绍的旋转如此之慢。 好吧,我来到这里:

    def rotate(self:'vector', angle:'rotation angle') -> 'vector':
        ??????

在这一点上,如果你知道如何旋转向量,你应该去上和问号填写。 通过逆时针旋转;否则,请与我承担一个更简单的情况下, 90度。 这个人是不是很难得出一个纸条:

    def rotate_90(self:'vector') -> 'rotated vector':
        new_x = - self.y
        new_y =   self.x
        return Vector(new_x, new_y)

x_axis = Vector(1, 0)
y_axis = Vector(0, 1)

print(x_axis.rotate_90(), y_axis.rotate_90())

现在给出(0, 1) (-1, 0) 运行它自己!

  • 问:证明flip = rotate_90 ◦ rotate_90

无论如何,我不会隐藏较长的秘诀:

import math   # we'll need math from now on
  ...

class Vector:

      ...

    def rotate(self:'vector', angle:'rotation angle') -> 'rotated vector':
        cos = math.cos(angle)
        sin = math.sin(angle)
        new_x = cos * self.x - sin * self.y
        new_y = sin * self.x + cos * self.y
        return Vector(new_x, new_y)

现在让我们尝试沿线的东西:

print(x_axis.rotate(90), y_axis.rotate(90))

如果你希望同样的结果之前, (0, 1) (-1, 0)你一定会失望。 该代码打印:

(-0.448073616129, 0.893996663601) (-0.893996663601, -0.448073616129)

男孩,是丑陋!

  • 表示法:我会说,我们应用操作rotate(90)x在上面的例子。 我们所获得的知识是rotate(90) != rotate_90

  • 问:这里发生了什么? 如何表达rotate_90来讲rotate ? 如何表达flip来讲rotate

胀缩

这些旋转是当然是有用的,但他们不是,你需要做的,即使在2D图形的一切。 请看下面的转换:

    def dilate(self:'vector', axe_x:'x dilation', axe_y:'y dilation'):
        '''Dilates a vector along the x and y axes'''
        new_x = axe_x * self.x
        new_y = axe_y * self.y
        return Vector(new_x, new_y)

这种dilate的东西扩张的xy轴的可能不同的方式。

  • 练习:填写问号dilate(?, ?) = flipdilate(?, ?) = reflect_x

我将使用这个dilate函数证明一件事数学家叫可交换 :那就是,对于每一个参数值abcd你可以肯定的是

dilate(a, b) ◦ dilate(c, d) = dilate(c, d) ◦ dilate(a, b)
  • 练习:证明这一点。 此外,这是真的,对于所有的参数值可能与下面将持有?

    • rotate(a) ◦ rotate(b) = rotate(b) ◦ rotate(a)
    • dilate(a, b) ◦ rotate(c) = rotate(c) ◦ dilate(a, b)
    • rotate(a) ◦ __mul__(b) = __mul__(b) ◦ rotate(a)

矩阵

让我们总结所有我们在这里,我们的运营商对向量的东西x

  • flipreflect_x*rotate(angle)dilate(x, y)

从中可以做一些很疯狂的东西一样

  • flip ◦ rotate(angle) ◦ dilate(x, y) ◦ rotate(angle_2) ◦ reflect_y + reflect_x = ???

当你创造更多,更复杂的表达式,人们希望的某种秩序,突然减少所有可能的表达式有用的形式。 不要害怕! 奇妙的是,每个以下形式的表达上面可以简化为

    def ???(self:'vector', parameters):
        '''A magical representation of a crazy function'''
        new_x = ? * self.x + ? * self.y
        new_y = ? * self.x + ? * self.y
        return Vector(new_x, new_y)

一些数字和/或参数而不是? 秒。

  • 例如:制定出什么样的价值观“?” 对于__mul__(2) ◦ rotate(pi/4)
  • 又如:用于同样的问题dilate(x, y) ◦ rotate(pi/4)

这让我们写一个通用的函数

    def transform(self:'vector', m:'matrix') -> 'new vector':
        new_x = m[0] * self.x + m[1] * self.y
        new_y = m[2] * self.x + m[3] * self.y
        return Vector(new_x, new_y)

这将需要的任何数字4元组,称为基质 ,并将其应用到向量x 。 下面是一个例子:

rotation_90_matrix = (0, -1, 1, 0)
print(v, v.rotate_90(), v.transform(rotation_90_matrix))

该打印(5, 3) (-3, 5) (-3, 5) 请注意,如果你申请transform与任何矩阵原点,你仍然可以产地:

origin = Vector(0, 0)
print(origin.transform(rotation_90_matrix))
  • 练习:是什么元组m描述flipdilate(x, y) rotate(angle)

当我们与零件Vector类,这里是一个锻炼对于那些谁想要测试自己的两个矢量数学知识和技能Python的:

  • 最后一战:加入了Vector类的所有矢量操作,你可以想出(你有多少个标准运营商可以为超载载体看看我的答案吗?)。

2.矩阵:重载

正如我们在上一节中发现,一个矩阵可以想到的简写,使我们能够以简单的方式编码向量操作。 例如, rotation_90_matrix编码由90度的旋转。

Matrix对象

现在,我们从载体转移我们的注意力转向矩阵,我们应该通过各种手段对矩阵一类为好。 此外,在功能Vector.transform(...)矩阵的角色上面有所歪曲。 这是更常见的m是固定的,而矢量的变化,所以从现在开始,我们的变革将是矩阵类的方法:

class Matrix:

    def __init__(self:'new matrix', m:'matrix data'):
        '''Create a new matrix.

        So far a matrix for us is just a 4-tuple, but the action
        will get hotter once The (R)evolution happens!

        '''
        self.m = m

    def __call__(self:'matrix', v:'vector'):
        new_x = self.m[0] * v.x + self.m[1] * v.y
        new_y = self.m[2] * v.x + self.m[3] * v.y
        return Vector(new_x, new_y)

如果你不知道的Python, __call__重载的含义(...)为基体,所以我可以使用标准的符号作用于一个向量的矩阵。 此外,矩阵利用单个大写字母通常写:

J = Matrix(rotation_90_matrix)
print(w, 'rotated is', J(w))
  • 练习:重复使用以前练习矩阵这个例子。

加成

现在,让我们看看我们还有什么可以做的矩阵。 请记住,矩阵m其实只是一个编码向量上的operaton方式。 请注意,对于两个函数m1(x)m2(x)余可以创建新的函数(使用拉姆达符号 ) m = lambda x: m1(x) + m2(x) 事实证明,如果m1m2分别由矩阵方式编码,也可以编码这种m采用矩阵

  • 练习:通过你可能有这种说法的任何困难想。

你只需要添加它的数据,例如(0, 1, -1, 0) + (0, 1, -1, 0) = (0, 2, -2, 0) 以下是如何添加两个元组在Python,有一些非常有用的和高度Python的技巧:

    def __add__(self:'matrix', snd:'another matrix'):
        """This will add two matrix arguments.

        snd is a standard notation for second argument.
        (i for i in array) is Python's powerful list comprehension.
        zip(a, b) is used to iterate over two sequences together

        """

        new_m = tuple(i + j for i, j in zip(self.m, snd.m))
        return Matrix(new_m)

现在我们可以写出这样的表达式J + J甚至J + J + J ,但要看到,我们必须弄清楚如何打印矩阵的结果。 一种可能的方法是将打印数字的4元组,但让我们从一个暗示Matrix.__call__这些数字应该组织成一个功能2x2块:

    def as_block(self:'matrix') -> '2-line string':
        """Prints the matrix as a 2x2 block.

        This function is a simple one without any advanced formatting.
        Writing a better one is an exercise.

        """

        return ('| {0} {1} |\n' .format(self.m[0], self.m[1]) +
                '| {0} {1} |\n' .format(self.m[2], self.m[3]) )

如果你看一下你会发现这个行动功能还有一定的提升空间:

print((J + J + J).as_block())
  • 练习:写一个更好的函数Matrix.__str__将圆的数字和固定长度的字段打印出来。

现在,你应该能够编写矩阵旋转:

def R(a: 'angle') -> 'matrix of rotation by a':
    cos = math.cos(a)
    sin = math.sin(a)
    m = ( ????? )
    return Matrix(m)
  • 练习:检查代码Vector.rotate(self, angle)和问号填写。 测试用

     from math import pi print(R(pi/4) + R(-pi/4)) 

乘法

我们可以用一个参数功能做的最重要的事情是它们组合: f = lambda v: f1(f2(v)) 如何镜像与矩阵? 这就要求我们必须研究如何Matrix(m1) ( Matrix(m2) (v))的作品。 如果你展开它,你会发现,

m(v).x = m1[0] * (m2[0]*v.x + m2[1]*v.y) + m1[1] * (m2[2]*v.x + m2[3]*v.y)

同样地,对于m(v).y ,其中,如果打开括号,看上去非常类似于Matrix.__call__使用新的元组m ,使得m[0] = m1[0] * m2[0] + m1[2] * m2[2] 因此,让我们以此为新definiton一个提示:

    def compose(self:'matrix', snd:'another matrix'):
        """Returns a matrix that corresponds to composition of operators"""

        new_m = (self.m[0] * snd.m[0] + self.m[1] * snd.m[2],
                 self.m[0] * snd.m[1] + self.m[1] * snd.m[3],
                 ???,
                 ???) 
        return Matrix(new_m)
  • 练习:在这里问号填写。 与测试

     print(R(1).compose(R(2))) print(R(3)) 
  • 数学锻炼:证明R(a).compose(R(b))总是相同R(a + b)

现在让我说实话:此compose函数实际上是数学家如何决定矩阵。 这是有意义的符号: A * B是decribes运营商矩阵A ○ B当我们将看到未来还有更深层次的原因,称之为“乘法”为好。

在Python开始使用乘法所有我们需要做的是在如此责令Matrix类:

    class Matrix:

          ...

        __mul__ = compose
  • 锻炼:计算(R(pi/2) + R(pi)) * (R(-pi/2) + R(pi)) 尽量先找到自己的答案在一张纸上。

规则+*

让我们做一些好名字对应于矩阵dilate(a, b)运营商。 现在有什么错D(a, b)但我会用一个机会来介绍一个标准的符号:

def diag(a: 'number', b: 'number') -> 'diagonal 2x2 matrix':
    m = (a, 0, 0, b)
    return Matrix(m)

尝试print(diag(2, 12345))看看为什么它被称为对角矩阵。

之前由于操作的成分被认为是不总是交换, *运营商将不会总是可交换的矩阵两种。

  • 练习:回去必要时刷新可交换的事情。 然后给予基质的实例AB ,从制成Rdiag ,使得A * B不等于B * A

这是有些奇怪,因为乘法数字始终是可交换的,并提出了一个问题,即是否compose真不愧被称为__mul__ 。 这里有相当多的是规则+* 满足:

  1. A + B = B + A
  2. A * (B + C) = A * B + A * C
  3. (A + B) * C = A * C + B * C
  4. (A * B) * C = A * (B * C)
  5. 有被称为操作A - B(A - B) + B = A

    • 练习:证明这些语句。 如何界定A - B来讲+*diag ? 什么A - A等于? Add方法__sub__到类Matrix 。 如果你计算会发生什么R(2) - R(1)*R(1) 什么它应该是相等?

(A * B) * C = A * (B * C)平等叫做可结合并且是特别好,因为这意味着我们不必担心把括号形式的表达式A * B * C

print(R(1) * (diag(2,3) * R(2)))
print((R(1) * diag(2,3)) * R(2))

让我们来看看类似物常规的数字01和减:

zero = diag(0, 0)
one = diag(1, 1)     

用下面的易核实补充:

  1. A + zero = A
  2. A * zero = zero
  3. A * one = one * A = A

规则变得完整,在这个意义上,有他们的一个简短的名称: 环公理 。 因此,数学家会说矩阵形成 ,并且他们确实一直使用符号+*谈论戒指的时候,和这样,我们就要。

使用它可以很容易地计算从上一节表达的规则:

(R(pi/2) + R(pi)) * (R(-pi/2) + R(pi)) = R(pi/2) * R(-pi/2) +  ... = one + ...
  • 练习:完成这一点。 证明(R(a) + R(b)) * (R(a) - R(b)) = R(2a) - R(2b)

仿射变换

时间回到我们如何定义矩阵:他们是一个快捷方式,一些操作可以用向量做的,所以它的东西,你可以实际绘制。 你可能想用一支笔或看别人建议,看看不同的平面变换的实例材料。

在我们将寻找那些仿射谁看“相同的”无处不在(没有弯曲)的变换,那些。 例如,周围的一些点的旋转(x, y)的资格。 现在,这一个不能被表示为lambda v: A(v) ,但在所用的形式被写入lambda v: A(v) + b对于某些基质A和矢量b

  • 练习:找到Ab ,使得由旋转pi/2周围的点(1, 0)具有上面的形式。 他们是独一无二的?

注意,对于每一个矢量存在的仿射变换其是由向量的偏移

仿射变换可以伸展或扩张的形状,但它应该以同样的方式的确无处不在。 现在,我希望你们相信,由变换下一个固定数量的任何数字变化的区域。 对于由矩阵给定的变换A这个coeffiecient被称为的行列式 A并且可以计算应用公式用于一个区域的两个向量A(x_axis)A(y_axis)

    def det(self: 'matrix') -> 'determinant of a matrix':
        return self.m[0]*self.m[3] - self.m[1] * self.m[2]

作为一种健全检查, diag(a, b).det()等于a * b

  • 练习:请确认。 当一个参数为0时会发生什么? 当它的消极的?

正如你所看到的,旋转矩阵的行列式总是相同的:

from random import random
r = R(random())
print (r, 'det =', r.det())

约一个有趣的事情det是,它是乘法(它定义一种如下,如果你打坐足够长的时间):

A = Matrix((1, 2, -3, 0))
B = Matrix((4, 1, 1, 2))
print(A.det(), '*', B.det(), 'should be', (A * B).det())

你可以用矩阵做一个有用的东西是写两个线性方程的系统

A.m[0]*v.x + A.m[1]*v.y = b.x
A.m[2]*v.x + A.m[3]*v.y = b.y

在一个更简单的方法: A(v) = b 。 让我们来解决系统,因为他们教(部分)高中:通过乘以第一方程式Am[3] ,第二通过-Am 1 ,并添加(如有疑问,这样做在一张纸上),以解决vx

如果你真的尝试过,你应该已经得到A.det() * vx = (Am[3]) * bx + (-Am[1]) * by ,这表明你总是可以得到v乘以b一些其他矩阵。 该矩阵被称为 A

    def inv(self: 'matrix') -> 'inverse matrix':
        '''This function returns an inverse matrix when it exists,
        or raises ZeroDivisionError when it doesn't. 

        '''
        new_m = ( self.m[3] / self.det(), -self.m[1] / self.det(),
                  ????? )
        return Matrix(new_m)

正如你看到的,这种方法大声失败时矩阵的行列式为零。 如果你真的想你可以抓住这个厚望有:

try:
    print(zero.inv())
except ZeroDivisionError as e: ...
  • 练习:完成方法。 证明逆矩阵不存在时self.det() == 0 。 写分矩阵并测试它的方法。 使用逆矩阵求解的方程A(v) = x_axisA上面所定义)。

鲍尔斯

逆矩阵的主要特性是, A * A.inv()总是等于one

  • Exercise: check that yourself. Explain why that should be so from the definition of inverse matrix.

That's why mathematicians denote A.inv() by A-1. How about we write a nice function to use A ** n notation for An? Note that the naive for i in range(n): answer *= self cycle is O(|n|) which is certainly too slow, because this can be done with a complexity of log |n|:

    def __pow__(self: 'matrix', n:'integer') -> 'n-th power':
        '''This function returns n-th power of the matrix.

        It does it more efficiently than a simple for cycle. A
        while loop goes over all bits of n, multiplying answer
        by self ** (2 ** k) whenever it encounters a set bit.

        ...
  • Exercise: Fill in the details in this function. Test it with

    X, Y = A ** 5, A ** -5 print (X, Y, X * Y, sep = '\n')

This function only works for integer values of n, even though for some matrices we can also define a fractional power, such as square root (in other words, a matrix B such that B * B = A).

  • Exercise: Find a square root of diag(-1, -1). Is this the only possible answer? Find an example of matrix that doesn't have a square root.

Bonus: Complex numbers

Here I'm going to introduce you to the subject in exactly one section! Since it's a complex subject, I'm likely to fail, so please forgive me in advance.

First, similarly to how we have matrices zero and one, we can make a matrix out of any real number by doing diag(number, number). Matrices of that form can be added, subtracted, multiplied, inverted and the results would mimic what happens with the numbers themselves. So for all practical purposes, one can say that, e.g., diag(5, 5) is 5.

However, Python doesn't know yet how to handle expressions of the form A + 1 or 5 * B where A and B are matrices. If you're interested, you should by all means go and do the following exercise or look at my implementation (which uses a cool Python feature called decorator); otherwise, just know that it's been implemented.

  • Exercise for gurus: Change the operators in a Matrix class so that in all standard operations where one of operands is a matrix and another a number, the number is automatically converted to the diag matrix. Also add comparison for equality.

Here's an example test:

print( 3 * A - B / 2 + 5 )

Now here's the first interesting complex number: the matrix J, introduced in the beginning and equal to Matrix((0, 1, -1, 0)), has a funny property that J * J == -1 (try it!). That means J is certainly not a normal number, but, as I just said, matrices and numbers easily mix together. For example,

(1 + J) * (2 + J) == 2 + 2 * J + 1 * J + J * J = 1 + 3 * J

using the rules listed some time before. What happens if we test this in Python?

(1 + J) * (2 + J) == 1 + 3*J

That should happily say True. Another example:

(3 + 4*J) / (1 - 2*J) == -1 + 2*J 

As you might have guessed, the mathematicians don't call those 'crazy numbers', but they do something similar - they call expressions of the form a + b*J complex numbers. Because those are still instances of our Matrix class, we can do quite a lot of operations with those: addition, subtraction, multiplication, division, power - it's all already implemented! Aren't matrices amazing?

I have overlooked the question of how to print the result of operation like E = (1 + 2*J) * (1 + 3*J) so that it looks like an expression with J rather than a 2x2 matrix. If you examine it carefully, you'll see that you need to print the left column of that matrix in the format ... + ...J (just one more nice thing: it's exactly E(x_axis)!) Those who know the difference between str() and repr() should see it's natural to name a function that would produce expression of such form as repr().

  • Exercise: Write the function Matrix.__repr__ that would do exactly that and try some tests with it, like (1 + J) ** 3, first computing the result on paper and then trying it with Python.

  • Math question: What is the determinant of a + b*J? If you know what the absolute value of complex number is: how they are connected? What is the absolute value of a? of a*J?

3. Matrices: The (R)evolution

In the final part of this trilogy we will see that everything is a matrix. We'll start with general M x N matrices, and find out how vectors can be thought of as 1 x N matrices and why numbers are the same as diagonal matrices. As a side note we'll explore the complex numbers as 2 x 2 matrices.

最后,我们将学习编写使用矩阵仿射和射影变换。

因此,规划的类[MNMatrix, NVector, Affine, Projective]

我想如果你能和我一起承担,直到在这里,你可能会感兴趣的这部续集,所以我想听到的话,我应该继续这样(在哪里,因为我非常相信我超越单个文档的认为是合理的长度)。



Answer 2:

麻省理工学院在很多他们的数学课程,材料的在线http://ocw.mit.edu/OcwWeb/Mathematics/ 。 一旦你的基础知识之后,他们的物理笔记在网上了。



Answer 3:

这是http://en.wikipedia.org/wiki/Computer_graphics 。 两个关键概念是http://mathworld.wolfram.com/LinearTransformation.html和http://mathworld.wolfram.com/AffineTransformation.html 。



Answer 4:

这MIT文档是一个必须要得到改造的基础知识非常了解。

http://stellar.mit.edu/S/course/6/fa08/6.837/courseMaterial/topics/topic2/lectureNotes/03_transform/03_transform.pdf



Answer 5:

一个初学者,最好的书是卡尔·迈耶的“矩阵分析与应用线性代数”。

你可以在这里在线查看整个书(尽管它有版权水印): http://www.matrixanalysis.com/DownloadChapters.html

你可能想看看第5章第。 326 - 332,其覆盖在旋转三维计算机图形



Answer 6:

你可能想看看通过我雄林,林一雄(ISBN:9812560874) 几何线性代数 。 这本书对你想要(2和3维向量空间的线性变换)什么,并用满,渐进细节(300页每个维度)的几何方法把它专门针对。 恐怕这不是随意购买,但你应该能够找到它在任何好的大学图书馆。 否则Bookfinder应该帮助你在一个相对适中的价格得到它。



Answer 7:

吉姆·赫弗龙的自由线性代数教科书是非常好的。 不像太多的免费电子书,吉姆显然已经手艺一个优秀的读者,并介绍了线性代数的时间。 这不是过分与正规的数学写作,这往往过于密集与定理和证明是很容易理解的负担。 它还含有大量的线性代数的实际应用确实很好的例子 - 坐标变换是一个例子。 你不能击败的价格,而且还配备了习题可选的解决方案。

PS如果坐标转换是你的事,你和线性代数完成后,你可能有兴趣在微分几何。



Answer 8:

这些都是我找到的信息。 他们中有些人可能是你宝贵的:

理论:

  • Woflrams关于矩阵的信息 ,并在维基百科上的其他的人
  • 由帕姆诺顿矩阵 -很不错的书,可在谷歌图书是免费的。
  • 正投影和透视投影
  • 在MSDN 3D转换

(搜索“矩阵”在谷歌图书给你很多lecutures,其中一些与变革直接连接的- 这是第一个成果之一,但我欢呼你检查了。)

  • 文章喜欢这一个 ,也许这还是这很容易与谷歌的帮助下发现的,所以我不会发布更多。
  • 也有关于StackOverflow.com矩阵的几个问题: 使用3D变换矩阵和如何应用转换矩阵? 只是最初的几个例子,你可以找到更多寻找矩阵或数学的标签。

我也鼓励(我不知道这是否是正确的字,我刚学英语)你,去寻找这类信息在这些书籍之一(尽管它们不是免费的,但你可以找到的大部分地区在谷歌图书旧的):

  1. 游戏编程宝石7
  2. 游戏编程精粹6
  3. 游戏编程宝石5
  4. 游戏编程宝石4
  5. 游戏编程宝石3
  6. 游戏编程精粹2
  7. 游戏编程精粹

每个市场有关的数学宝石节 - 有很多巧妙的技巧那里。 那些书是值得每一分钱。

还有GPU编程的宝石,所以你可以尝试他们。

实践:

  • OpenGL的预订在维基百科有大约在OpenGL矩阵部分(另外,在OpenGL使用矩阵被描述在这里和在这里 )
  • 在绘制DirectX 3D的房间 +信息关于矩阵变换。

如果我会找到更多的,我会编辑在这里添加链接,但说实话 - 我发现这些链接在约10分钟,同时使用谷歌的。 世界上最流行的事情了浏览器存储数据 - 是的,“一切”是指矩阵了。

队友的欢呼声。



Answer 9:

我想你应该花几天时间做点积和叉积在3D矢量。 然后学习三角函数和向量之间的关系。 此后,矩阵将会使很多更有意义给你。



Answer 10:

麻省理工学院开放式课程对线性代数吉尔伯特斯特朗课程。 令人难以置信的讲座由一个不可思议的人; 如果你的矩阵的了解仅来自节目源(如MATLAB)导出然后线性代数课程一定会让你的基本面做疯狂的事情矩阵。

http://www.ocw.cn/OcwWeb/Mathematics/18-06Spring-2005/VideoLectures/index.htm



文章来源: Matrix transforms; concepts and theory, are there any free resources for learning practically? [closed]