python定义二维三维矢量的运算(一)
作者:竹影
注:除了一些语句解释学习是问了AI的,所有的语句都是一点一点敲的,算法思想也是作者思考的,而且这个问题的泛用性很大,肯定也有大佬想出来啦,这里只是作者展示一下自己的思考过程和学习过程,仅供讨论~
作者很想要通过编程来研究一些问题,适逢作者开始学习大学物理(),如果能够用编程思想来解决一些问题那真是泰豪辣(其实是自己想玩一玩
那么在这里就记录一下我的学习开发过程啦,如果有大佬发现有什么问题或者是有什么建议,麻烦指出来啦(
首先想要用编程来复现大物模型。。。得选择编程语言吧,作者专业目前学的是C语言,但是C语言实现感觉太过繁琐了,于是我就把目光看到了python,虽然是解释型语言,但是语法的简洁和图形化的简便确实让人心动呢,所以我开始学习这门语言——python的oop
现在编程语言选好啦,那么就是一些工具了,知道python有很多库很好用,但是为了磨(虐)练(待)自己,我还是选择自己先试着写一写,也为了熟悉这门语言
那么在一开始的运动学里,矢量的地位非常重要,那么在这数学的前置问题中,矢量的运算成为我的首要目标
一、梦开始的地方——二维向量
二维向量,高中就学习了的内容,先从这里入手可以让我先试试水温
def __init__(self,x,y):
self.x = x
self.y = y
self.angleTan = y / x
self.len = m.sqrt(x**2 + y**2)
属性嘛,还有什么比坐标更关键的呢,有了坐标就可以算与坐标轴的夹角,以及自身的长度,都是很关键的
那么为了让我们的计算融合进python的本身语法而不那么突兀,就得调用一堆特殊方法了呢
首先,我希望print(vector)
能够被正确表示
def __str__(self):
return f"<{self.x},{self.y}>"
在这里我使用尖括号来表示向量,虽然这很不符合规范,但我还是想把向量和坐标区别开来QAQ
其次,我希望a + b
能够自动被系统识别为向量减法,而不是调用一堆毫无美感的函数去实现向量加减
def __add__(self, other):
if self.dimension != other.dimension:
raise ValueError("向量维度不一致,不可以做加法!")
return Vector2D(self.x+other.x,self.y+other.y)
于是,在进行初步尝试后:
p = Vector2D(1,2)
q = Vector2D(3,6)
print(f"{p} + {q} = {q + p}")
我成功的得到了以下输出结果:
<1,2> + <3,6> = <4,8>
看来,似乎也没有那么困难嘛~
二、向着通用性进发
于是,我修改了我的代码:
首先,我需要我的类能够同时赋值二维向量和三维向量
def __init__(self,coodinates):
self.codi = coodinates
self.dimension = len(coodinates)
if self.dimension == 2:
self.len = m.sqrt(self.codi[0]**2 + self.codi[1]**2)
self.angleTan = self.codi[1] / self.codi[0]
elif self.dimension == 3:
self.len = m.sqrt(sum(x**2 for x in self.codi))
self.angleCos = []
for i in range(3):
self.angleCos.append(self.codi[i] / self.len)
else:
raise TypeError("不允许更高维度的向量啦")
现在,我使用了if判断语句来识别二维和三维向量,并且我改变了向量定义的方法,用可变长度的列表来获取坐标值,并将维度self.dimension
作为每个实例的一个属性,通过列表长度来获取
基于不同的向量,我也设置了不同的属性:二维向量通过长度和与x轴夹角的正切值作为辅助属性;而三维向量则是通过长度和方向余弦序列来确定,其中方向余弦序列的顺序是[x轴方向余弦,y轴方向余弦,z轴方向余弦]
而更高维度的向量不在此基础范畴啦,不过可能会在后续线性代数的文件里面尝试复现捏
然后我发现我很讨厌在这个文件里面看到"不允许更高维度的向量啦"这样的直接报错信息(是因为想装b吧hhh),于是我单独创建了一个ErrorDirec.py
专门存放这样报错的“宏定义”(原谅我用了其他编程语言的词汇www,毕竟作者真的很不专业)
于是,一通操作后,代码现在的代码变成了:
import ErrorDirec as err
def __str__(self):
return f"{self.codi}"
def update_private(self,other):
self._zipped = zip(self.codi,other.codi)
def __add__(self, other):
if self.dimension != other.dimension:
raise ValueError(err.ADD_ERROR)
return Vector([a + b for a , b in self._zipped])
def __sub__(self,other):
if self.dimension != other.dimension:
raise ValueError(err.SUB_ERROR)
return Vector(a - b for a , b in self._zipped)
#测试
p = Vector([1,2])
q = Vector([3,5])
a = Vector([1,2,3])
e = a + q
print(p)
print(f"{p} + {q} = {q+p}")
这里定义了一个私有属性self._zipped = zip(self.codi,other.codi)
来存放元组,真的是因为懒得打那么多。。。
啊,已经写了这么多工作了,向量的加减已经完全没问题了呢
那么这一期暂时到这里吧~作者写这个没有任何其他的目的,就是觉得好玩www,那么还有向量的其他工作捏
Vector类计划:
方法:
加法减法
数乘
点乘
叉乘
显示信息
。。。。(想到了再写吧www)
拜拜~