一、向量

# -*- coding: UTF-8 -*-
from math import sqrt,acos,pi
from decimal import Decimal,getcontext
import pdb

getcontext().prec = 15 # 上下文的 prec 属性控制着作为算术运算结果所创建的新值的精度。

class Vector:
    """向量实体"""


    def __init__(self, coordinate):
        """初始化函数"""

        try:
            if not coordinate:
                raise ValueError
            self.coordinate = tuple([Decimal(x) for x in coordinate])
            self.dimension = len(coordinate)

        except ValueError:
            raise ValueError("向量坐标不能为空!")

        except TypeError:
            raise TypeError("坐标类型需为可迭代对象")

    def __str__(self):
        """toString"""

        return "Vector:{}".format(self.coordinate)

    def __eq__(self,v):
        return self.coordinate == v.coordinate

    def plus(self,v):
        """向量相加"""
        return Vector([x+y for x,y in zip(self.coordinate,v.coordinate)])

    def minus(self,v):
        """向量相减"""
        return Vector([x-y for x,y in zip(self.coordinate,v.coordinate)])

    def times_scalar(self,c):
        """乘标量"""
        new_coordinates = [Decimal(c)*x for x in self.coordinate]
        return Vector(new_coordinates)

    def magnitude(self):
        """向量大小"""
        return Decimal(sqrt(sum([x**2 for x in self.coordinate])))

    def normalized(self):
        try:
            return self.times_scalar(Decimal('1.0')/self.magnitude())
        except ZeroDivisionError:
            raise Exception("不能标准化零向量")

向量点积

这里写图片描述
这里写图片描述
这里写图片描述

    def dot(self,v):
        """点积"""
        return sum([x*y for x,y in zip(self.coordinate,v.coordinate)])

    def angle_with(self,v,in_degrees=False):
        """两向量夹角"""
        u1 = self.normalized()
        u2 = v.normalized()
        angle_in_radians = acos(u1.dot(u2))

        if(in_degrees):
            degress_per_radian = 180./pi 
            return angle_in_radians * degress_per_radian
        else:
            return angle_in_radians

平行向量:

平行向量,也叫共线向量。是指方向相同或相反的非零向量。零向量和任何向量平行。

def is_zero(self,tolerance=1e-10):
        """
            是否为零向量

            Parameters:
                tolerance:当向量模小于该数时,判断为0
        """
        return self.magnitude() < tolerance

    def is_parallel_to(self,v):
        """
            两向量是否平行

            1)零向量与任一向量平行
            2)两向量夹角为0或π时,两向量平行
        """
        return (self.is_zero() or
                v.is_zero() or
                self.angle_with(v) == 0 or
                self.angle_with(v) == pi)

正交向量

“正交向量”是一个数学术语,指点积为零的两个或多个向量。几何向量的概念在线性代数中经由抽象化,得到更一般的向量概念。此处向量定义为向量空间的元素,要注意这些抽象意义上的向量不一定以数对表示,大小和方向的概念亦不一定适用。在三维向量空间中, 两个向量的内积如果是零, 那么就说这两个向量是正交的。正交最早出现于三维空间中的向量分析。 换句话说, 两个向量正交意味着它们是相互垂直的。若向量α与β正交,则记为α⊥β。

    def is_orthogonal_to(self,v,tolerance=1e-10):
        """两向量是否正交"""
        return abs(self.dot(v)) < tolerance

向量投影

这里写图片描述
计算投影的方法
这里写图片描述

    def proj_with(self,basis):
        """求投影向量"""

        try:
            u = basis.normalized()
            proj_magnitude = self.dot(u) #向量v在基向量上投影的大小等于向量v与标准化基向量的点积
            return u.times_scalar(proj_magnitude) 
        except Exception as e:
            raise Exception("不能标准化零向量")

    def orthogoal_with(self,basis):
        """求正交向量"""

        try:
            proj = self.proj_with(basis)
            return self.minus(proj)
        except Exception as e:
            raise Exception("不能标准化零向量")

向量积(来自百度百科)

这里写图片描述
这里写图片描述
这里写图片描述

 def cross(self,v):
        """向量积"""

        try:
            x_1,y_1,z_1 = self.coordinate
            x_2,y_2,z_2 = v.coordinate
            return Vector([y_1*z_2 - y_2*z_1,
                          -(x_1*z_2 - x_2*z_1),
                          x_1*y_2 - x_2*y_1])
        except ValueError as e:
            msg = str(e)
            if msg == 'need more than 2 values to unpack':
                self_embedded_in_R3 = Vector(self.coordinate + ('0',))
                v_embedded_in_R3 = Vector(v.coordinate + ('0',))
                return self_embedded_in_R3.cross(v_embedded_in_R3)
            elif(msg == 'too many values to unpack' or
                 msg == 'need more than 1 value to unpack'):
                raise Exception("仅支持两维或三维的向量积运算")
        else:
            raise e

这里写图片描述

    def area_of_parallelogram_with(self,v):
        """平行四边形面积"""

        new_coordinates = self.cross(v)
        return new_coordinates.magnitude()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值