几何学里有两大基本概念
点和向量
本质上,点是空间上的一个位置
向量则是位置改变的对象
向量的长度和方向
向量用列来表示而点用(x,y,z,….)来表示
点和向量的重要区别之一是向量没有固定位置
每个向量在x y 轴的变化量
用python 实现定义vactor 模块
要有定义,打印,判断相等等功能
向量的加减
标量乘法
向量内积 向量乘以向量 inner product v向量*w向量=|v|*|w|*cos
向量内积是个数字不是向量
用反三角函数可以算出那个角度 =v向量*w向量/|v|*|w|
也可以理解为 角度=v向量的标准*w向量的标准
也可以用更好的方法 v向量*w向量=v1w1+v2w2+v3w3+…..
列表推导式(list comprehension)是利用其他列表创建新列表(类似于数学术语中的集合推导式)的一种方法。它的工作方式类似于for循环,也很简单
In [39]: [x*x for x in range(10)]
Out[39]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
重载运算符
''' object.__add__(self, other): +
object.__sub__(self, other): -
object.__mul__(self, other): *
object.__matmul__(self, other):@
object.__truediv__(self, other): /
object.__floordiv__(self, other): //
object.__mod__(self, other): %
object.__divmod__(self, other): divmod, divmod(a, b) = (a / b, a % b)
object.__pow__(self, other[, modulo]): **, pow()
object.__lshift__(self, other): <<
object.__rshift__(self, other): >>
object.__and__(self, other): &
object.__xor__(self, other): ^
object.__or__(self, other): |
'''
try raise 捕获异常
try:
# 判断是否是None
if not coordinates:
raise ValueError
# 坐标参数
self.coordinates = coordinates
# 维度参数
self.dimension = len(coordinates)
except ValueError:
# raise 是丢出一个错误
raise ValueError("坐标必须不是空")
except TypeError:
raise TypeError("坐标必须迭代")
向量长度^2=(x1,y1)^2+(x2,y2)^2
零向量表示没有变化的向量 大小是0
平行向量 0向量是任何向量的平行(parallel)向量 也是任何向量的正交向量
两个向量相乘为0 要么其中有一个向量为0 要么就是正交(orthogonal)向量
投影
projection of v向量 对于b向量来说
proj sub b(v) or v||
v向量=v平行向量+v垂直向量
v向量在b向量上的投影=(v向量*b的单位向量)*b的单位向量
向量积 cross product
输出的是向量
v向量*w向量=|v|*|w|*sin З
当角度等于0 或180的时候
向量积大小等于0向量
右手准则
右手大拇指指向v向量的方向,食指指向w向量方向,那么中指的方向就是向量积的方向向上
v向量*w向量=-(w向量*v向量)
交换乘法顺序会变成负极 我们称向量积为反交换的与可交换的点积对立
交换点积顺序不会影响结果
如果v[x1,y1,z1] w[x2,y2,z2] 那么 v*w =[(y1z2-y2z1) , -(x1z2-x2z1) ,(x1y2-x2y1)]
还可以用向量积算出这两个向量构成的四遍形的大小 根号 x1^2+y1^2+z1^2
空间里的点可以由通过的基准点 和向量来表示 y=kx+b
基本点 x0向量
指导向量 v
直线参数化
x(t)=x0+tV
描述没有共同点的方程组 三联方程 要三条直线交与同一个点 除了这种情况其他的我们都用不成立来形容(inconsistent)
# coding=utf-8
# 这是判断线的
from decimal import Decimal, getcontext
from Vector import Vector
getcontext().prec = 30
class Line(object):
NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found'
def __init__(self, normal_vector=None, constant_term=None):
self.dimension = 2
if not normal_vector:
all_zeros = ['0'] * self.dimension
normal_vector = Vector(all_zeros)
self.normal_vector = normal_vector
if not constant_term:
constant_term = Decimal('0')
self.constant_term = Decimal(constant_term)
self.set_basepoint()
def set_basepoint(self):
try:
n = self.normal_vector
c = self.constant_term
basepoint_coords = ['0'] * self.dimension
initial_index = Line.first_nonzero_index(n)
initial_coefficient = n[initial_index]
basepoint_coords[initial_index] = c / Decimal(initial_coefficient)
self.basepoint = Vector(basepoint_coords)
except Exception as e:
if str(e) == Line.NO_NONZERO_ELTS_FOUND_MSG:
self.basepoint = None
else:
raise e
def __str__(self):
num_decimal_places = 3
def write_coefficient(coefficient, is_initial_term=False):
coefficient = round(coefficient, num_decimal_places)
if coefficient % 1 == 0:
coefficient = int(coefficient)
output = ''
if coefficient < 0:
output += '-'
if coefficient > 0 and not is_initial_term:
output += '+'
if not is_initial_term:
output += ' '
if abs(coefficient) != 1:
output += '{}'.format(abs(coefficient))
return output
n = self.normal_vector
try:
initial_index = Line.first_nonzero_index(n)
terms = [write_coefficient(n[i], is_initial_term=(i == initial_index)) + 'x_{}'.format(i + 1)
for i in range(self.dimension) if round(n[i], num_decimal_places) != 0]
output = ' '.join(terms)
except Exception as e:
if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG:
output = '0'
else:
raise e
constant = round(self.constant_term, num_decimal_places)
if constant % 1 == 0:
constant = int(constant)
output += ' = {}'.format(constant)
return output
@staticmethod
def first_nonzero_index(iterable):
for k, item in enumerate(iterable):
if not MyDecimal(item).is_near_zero():
return k
raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG)
# 判断两条直线是否平行
def is_parallel_to(self, other):
# 判断两条直线是否平行就是判断两条直线的法向量是否平行
n1 = self.normal_vector
n2 = other.normal_vector
return Vector(n1).is_parallel_to(Vector(n2))
# 判断两条直线是同一条直线
def __eq__(self, other):
if self.normal_vector.is_zero():
if not other.normal_vector.is_zero():
return False
else:
diff = self.constant_term - other.constant_term
return MyDecimal(diff).is_near_zero()
elif other.normal_vector.is_zero():
return False
if not self.is_parallel_to(other):
return False
basepoint_diff = self.basepoint.minus(other.basepoint)
return basepoint_diff.is_orthogonal_to(self.normal_vector)
# 判断两条直线的交点 平行返回NONE 同一条就返回焦点就是这条直线,
def intersection_with(self, other):
try:
a, b = Vector(self.normal_vector).coordinates
c, d = Vector(other.normal_vector).coordinates
k1 = self.constant_term
k2 = other.constant_term
x = Decimal(d) * k1 - Decimal(b) * k2
y = Decimal(a) * k2 - Decimal(c) * k1
times=Decimal('1')/Decimal(a * d - b * c)
return Vector([x,y]).times_scalar(times)
except ZeroDivisionError:
if self == other:
return self
else:
return None
class MyDecimal(Decimal):
def is_near_zero(self, eps=1e-10):
return abs(self) < eps
my_line1 = Line([4.046, 2.836], 1.21)
my_line2 = Line([10.115, 7.09], 3.025)
my_line3 = Line([7.204, 3.182], 8.68)
my_line4 = Line([8.172, 4.114], 9.883)
my_line5 = Line([1.182, 5.562], 6.744)
my_line6 = Line([1.773, 8.343], 9.525)
# print my_line1.is_line_parallel(my_line2)
# print my_line1.is_same_line(my_line2)
print my_line1.intersection_with(my_line2)
# print my_line3.line_of_intersection(my_line4)
# print my_line5.line_of_intersection(my_line6)
# coding=utf-8
# 这是平面的
from decimal import Decimal, getcontext
from Vector import Vector
getcontext().prec = 30
class Plane(object):
NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found'
def __init__(self, normal_vector=None, constant_term=None):
self.dimension = 3
if not normal_vector:
all_zeros = ['0'] * self.dimension
normal_vector = Vector(all_zeros)
self.normal_vector = normal_vector
if not constant_term:
constant_term = Decimal('0')
self.constant_term = Decimal(constant_term)
self.set_basepoint()
def set_basepoint(self):
try:
n = self.normal_vector
c = self.constant_term
basepoint_coords = ['0'] * self.dimension
initial_index = Plane.first_nonzero_index(n.coordinates)
initial_coefficient = n.coordinates[initial_index]
basepoint_coords[initial_index] = c / Decimal(initial_coefficient)
self.basepoint = Vector(basepoint_coords)
except Exception as e:
if str(e) == Plane.NO_NONZERO_ELTS_FOUND_MSG:
self.basepoint = None
else:
raise e
def __str__(self):
num_decimal_places = 3
def write_coefficient(coefficient, is_initial_term=False):
coefficient = round(coefficient, num_decimal_places)
if coefficient % 1 == 0:
coefficient = int(coefficient)
output = ''
if coefficient < 0:
output += '-'
if coefficient > 0 and not is_initial_term:
output += '+'
if not is_initial_term:
output += ' '
if abs(coefficient) != 1:
output += '{}'.format(abs(coefficient))
return output
n = self.normal_vector
try:
initial_index = Plane.first_nonzero_index(n)
terms = [write_coefficient(n[i], is_initial_term=(i == initial_index)) + 'x_{}'.format(i + 1)
for i in range(self.dimension) if round(n[i], num_decimal_places) != 0]
output = ' '.join(terms)
except Exception as e:
if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG:
output = '0'
else:
raise e
constant = round(self.constant_term, num_decimal_places)
if constant % 1 == 0:
constant = int(constant)
output += ' = {}'.format(constant)
return output
# 判断两条直线是否平行
def is_parallel_to(self, other):
n1 = self.normal_vector
n2 = other.normal_vector
return n1.is_parallel_to(n2)
def __eq__(self, other):
if self.normal_vector.is_zero():
if not other.normal_vector.is_zero():
return False
else:
diff = self.constant_term - other.constant_term
return MyDecimal(diff).is_near_zero()
elif other.normal_vector.is_zero():
return False
if not self.is_parallel_to(other):
return False
basepoint_diff = self.basepoint.minus(other.basepoint)
return basepoint_diff.is_orthogonal_to(self.normal_vector)
@staticmethod
def first_nonzero_index(iterable):
for k, item in enumerate(iterable):
if not MyDecimal(item).is_near_zero():
return k
raise Exception(Plane.NO_NONZERO_ELTS_FOUND_MSG)
class MyDecimal(Decimal):
def is_near_zero(self, eps=1e-10):
return abs(self) < eps
my_plane1 = Plane(normal_vector=Vector([-0.412, 3.806, 0.728]), constant_term=-3.46)
my_plane2 = Plane(normal_vector=Vector([1.03, -9.515, 1.82]), constant_term=8.65)
print my_plane1.is_parallel_to(my_plane2)
print my_plane1 == my_plane2
第一 :我们要排列顺序变化而不影响交点
第二:我们乘以一个非零的数等式两边依然成立
第三,如果有两个等式,我们可以把一个等式多次加到另一个等式上面
高斯消元法
最简化的梯阵形式 RREF
判断系统是否无解是查看k=0?
判断方程组是否有唯一解 还是无数解
判断唯一解要看看在形成的三角型中 每个变量是否都是首项变量,即主变量
如果每个都是主变量那么就有唯一解 否者就有无数解
每个非主变量即自由变量都将成为独立参数表明解集的维度将等于自由变量的数量
一个自由变量那么解集就是一条直线, 2个自由变量,那么解集就是一个平面
如果a=[1,2,3],则a[::-1]=[3,2,1]
,也可以写上参数表示处理列表的一部分,例如a[2:0:-1]=[3,2],第一个参数表示起始点包括起始点,第二个参数表示结束点但不包括结束点。最后一个参数如果为负的话,需要保证第一个参数大于第二个参数,表示依次递减逆序,否则会输出空列表