Math 矩阵变换;概念和理论,是否有任何免费的资源用于实际学习?
最近,我从坐标中绘制图表和图形很有趣,我对使用矩阵变换坐标空间很感兴趣 我已经能够成功地缩放和反转二维坐标空间,但现在我的胃口大增。:)Math 矩阵变换;概念和理论,是否有任何免费的资源用于实际学习?,math,matrix,coordinates,hyperlink,Math,Matrix,Coordinates,Hyperlink,最近,我从坐标中绘制图表和图形很有趣,我对使用矩阵变换坐标空间很感兴趣 我已经能够成功地缩放和反转二维坐标空间,但现在我的胃口大增。:) 我在哪里可以找到关于矩阵、矩阵数学,特别是适用于二维和三维空间的清晰、信息丰富的(免费)教育材料?麻省理工学院的许多数学课程材料都在网上。一旦你掌握了基础知识,他们也会在线上物理笔记。这是。两个关键概念是,和。原始答案:我不确定您是否喜欢数学课程通常如何介绍矩阵。作为一名程序员,你可能会更喜欢任何一本像样的3D绘图书。它当然应该有非常具体的3x3矩阵。此外,找
我在哪里可以找到关于矩阵、矩阵数学,特别是适用于二维和三维空间的清晰、信息丰富的(免费)教育材料?麻省理工学院的许多数学课程材料都在网上。一旦你掌握了基础知识,他们也会在线上物理笔记。这是。两个关键概念是,和。原始答案:我不确定您是否喜欢数学课程通常如何介绍矩阵。作为一名程序员,你可能会更喜欢任何一本像样的3D绘图书。它当然应该有非常具体的3x3矩阵。此外,找出将教你的(投影几何是低维几何的一个非常美丽的领域,易于编程) 使用Python 3学习矩阵数学的迷你课程 内容:
[向量、添加、反射、旋转、放大、变换]
[Matrix、\uuuuu add\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu struuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
- 这个帖子很长。你可能会考虑打印这件事,然后慢下来,就像一天一部分。
- 代码是必不可少的。这是一门程序员的课程。锻炼也是必要的
- 您应该,其中包含所有这些代码以及更多内容
- 这是“2换1”的特价:您也可以在这里学习Python 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)
点翻转向量,你可以围绕x
或y
轴反射向量,你可以顺时针或逆时针旋转向量(在这里画图是个好主意)
让我们做一些简单的操作:
...
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())
- 问题:是否可以使用下面的操作来表示
?那反映呢翻转(…)
reflect\y
。因为我想让你停下来写你自己的版本。好的,这是我的:
def reflect_y(self:'vector') -> 'vector reflected around y axis':
return self.flip().reflect_x()
看,如果你看一下这个函数是如何计算的,它实际上非常简单。但是突然发生了一件惊人的事情:我能够只使用现有的转换flip
和reflect\ux
编写一个转换。总之,我关心的是,reflect_y
可以在派生类中定义,而不需要访问x
和y
,而且它仍然可以工作
数学家称这些函数为算子。他们会说reflect_y
是通过组合操作符flip
和reflect_x
获得的操作符,这是
用reflect_y=flip表示○ 反射(你应该看到一个小圆圈,一个Unicode符号25CB
)
- 注意:从现在起,我将非常自由地使用
=
符号来表示两个操作产生相同的结果,如上面的段落所示。这是一个“数学=
”,它是
所以如果我这样做了
print(v.reflect_y())
我得到结果(-5,3)
。去想象一下吧
< > >强>问题:< /强>考虑构图<代码>反射◦ 反映_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\u 90◦ 旋转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)
还有,孩子,这是丑陋的
- 表示法:在上面的示例中,我们将操作
应用于旋转(90)
。这个x
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(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)`
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)
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)
rotation_90_matrix = (0, -1, 1, 0) print(v, v.rotate_90(), v.transform(rotation_90_matrix))
origin = Vector(0, 0) print(origin.transform(rotation_90_matrix))
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)
J = Matrix(rotation_90_matrix) print(w, 'rotated is', J(w))
def __add__(self:'matrix', snd:'another matrix'): """This will add two matrix arguments. snd is a standard notation for the 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)
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())
def R(a: 'angle') -> 'matrix of rotation by a': cos = math.cos(a) sin = math.sin(a) m = ( ????? ) return Matrix(m)
from math import pi print(R(pi/4) + R(-pi/4))
m(v).x = m1[0] * (m2[0]*v.x + m2[1]*v.y) + m1[1] * (m2[2]*v.x + m2[3]*v.y)
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))
class Matrix: ... __mul__ = compose
def diag(a: 'number', b: 'number') -> 'diagonal 2x2 matrix': m = (a, 0, 0, b) return Matrix(m)
print(R(1) * (diag(2,3) * R(2))) print((R(1) * diag(2,3)) * R(2))
zero = diag(0, 0) one = diag(1, 1)
(R(pi/2) + R(pi)) * (R(-pi/2) + R(pi)) = R(pi/2) * R(-pi/2) + ... = one + ...
def det(self: 'matrix') -> 'determinant of a matrix': return self.m[0]*self.m[3] - self.m[1] * self.m[2]
from random import random r = R(random()) print (r, 'det =', r.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
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: ...
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 cycle. A while loop goes over all bits of n, multiplying answer by self ** (2 ** k) whenever it encounters a set bit. ...
print( 3 * A - B / 2 + 5 )
(1 + J) * (2 + J) == 2 + 2 * J + 1 * J + J * J = 1 + 3 * J
(1 + J) * (2 + J) == 1 + 3*J
(3 + 4*J) / (1 - 2*J) == -1 + 2*J