Python 画图 向量a在向量b上的投影(Projection of Vector a on Vector b)

Python 画图 向量a在向量b上的投影(Projection of Vector a on Vector b)

flyfish

向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影(Projection of Vector a ⃗ \vec{a} a on Vector b ⃗ \vec{b} b )是指向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 方向上的分量。这个投影可以理解为 a ⃗ \vec{a} a b ⃗ \vec{b} b 方向上“影子”的长度和方向,即下图紫色虚线。

在这里插入图片描述

数学定义

向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影向量 proj b ⃗ a ⃗ \text{proj}_{\vec{b}} \vec{a} projb a 可以通过以下公式计算:

proj b ⃗ a ⃗ = ( a ⃗ ⋅ b ⃗ b ⃗ ⋅ b ⃗ ) b ⃗ \text{proj}_{\vec{b}} \vec{a} = \left( \frac{\vec{a} \cdot \vec{b}}{\vec{b} \cdot \vec{b}} \right) \vec{b} projb a =(b b a b )b

这里:

  • a ⃗ ⋅ b ⃗ \vec{a} \cdot \vec{b} a b 是向量 a ⃗ \vec{a} a 和向量 b ⃗ \vec{b} b 的点积(内积),表示为:
    a ⃗ ⋅ b ⃗ = a 1 b 1 + a 2 b 2 + ⋯ + a n b n \vec{a} \cdot \vec{b} = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n a b =a1b1+a2b2++anbn
  • b ⃗ ⋅ b ⃗ \vec{b} \cdot \vec{b} b b 是向量 b ⃗ \vec{b} b 的模的平方,表示为:
    b ⃗ ⋅ b ⃗ = ∥ b ⃗ ∥ 2 = b 1 2 + b 2 2 + ⋯ + b n 2 \vec{b} \cdot \vec{b} = \| \vec{b} \|^2 = b_1^2 + b_2^2 + \cdots + b_n^2 b b =b 2=b12+b22++bn2
  • ( a ⃗ ⋅ b ⃗ b ⃗ ⋅ b ⃗ ) \left( \frac{\vec{a} \cdot \vec{b}}{\vec{b} \cdot \vec{b}} \right) (b b a b ) 是一个标量,表示 a ⃗ \vec{a} a b ⃗ \vec{b} b 方向上的分量的长度。
  • b ⃗ \vec{b} b 是向量 b ⃗ \vec{b} b 本身,用来确定投影的方向。

投影长度

向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影长度(标量形式)可以通过以下公式计算:

∣ proj b ⃗ a ⃗ ∣ = ∣ a ⃗ ⋅ b ⃗ ∣ ∥ b ⃗ ∥ |\text{proj}_{\vec{b}} \vec{a}| = \frac{|\vec{a} \cdot \vec{b}|}{\|\vec{b}\|} projb a =b a b

这里:

  • ∣ a ⃗ ⋅ b ⃗ ∣ |\vec{a} \cdot \vec{b}| a b 是向量 a ⃗ \vec{a} a 和向量 b ⃗ \vec{b} b 点积的绝对值。
  • ∥ b ⃗ ∥ \|\vec{b}\| b 是向量 b ⃗ \vec{b} b 的模长,表示为:
    ∥ b ⃗ ∥ = b 1 2 + b 2 2 + ⋯ + b n 2 \|\vec{b}\| = \sqrt{b_1^2 + b_2^2 + \cdots + b_n^2} b =b12+b22++bn2

几何意义

  1. 方向:投影向量 proj b ⃗ a ⃗ \text{proj}_{\vec{b}} \vec{a} projb a 的方向与向量 b ⃗ \vec{b} b 的方向相同(或相反,取决于点积的符号)。
  2. 长度:投影向量的长度表示 a ⃗ \vec{a} a b ⃗ \vec{b} b 方向上的分量的大小。

示例

假设 a ⃗ = ( 2 3 ) \vec{a} = \begin{pmatrix} 2 \\ 3 \end{pmatrix} a =(23) b ⃗ = ( 4 0 ) \vec{b} = \begin{pmatrix} 4 \\ 0 \end{pmatrix} b =(40),我们来计算 a ⃗ \vec{a} a b ⃗ \vec{b} b 上的投影。

  1. 计算点积
    a ⃗ ⋅ b ⃗ = 2 ⋅ 4 + 3 ⋅ 0 = 8 \vec{a} \cdot \vec{b} = 2 \cdot 4 + 3 \cdot 0 = 8 a b =24+30=8

  2. 计算 b ⃗ \vec{b} b 的模的平方
    b ⃗ ⋅ b ⃗ = 4 2 + 0 2 = 16 \vec{b} \cdot \vec{b} = 4^2 + 0^2 = 16 b b =42+02=16

  3. 计算投影向量
    proj b ⃗ a ⃗ = ( 8 16 ) ( 4 0 ) = 1 2 ( 4 0 ) = ( 2 0 ) \text{proj}_{\vec{b}} \vec{a} = \left( \frac{8}{16} \right) \begin{pmatrix} 4 \\ 0 \end{pmatrix} = \frac{1}{2} \begin{pmatrix} 4 \\ 0 \end{pmatrix} = \begin{pmatrix} 2 \\ 0 \end{pmatrix} projb a =(168)(40)=21(40)=(20)

  4. 计算投影长度
    ∣ proj b ⃗ a ⃗ ∣ = ∣ 8 ∣ 16 = 8 4 = 2 |\text{proj}_{\vec{b}} \vec{a}| = \frac{|8|}{\sqrt{16}} = \frac{8}{4} = 2 projb a =16 ∣8∣=48=2

因此,向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影向量是 ( 2 0 ) \begin{pmatrix} 2 \\ 0 \end{pmatrix} (20),投影长度是 2。

import matplotlib.pyplot as plt
import numpy as np

# 设置画布大小和背景颜色
fig, ax = plt.subplots(figsize=(8, 6))  # 创建一个新的图形并设置其大小
ax.set_facecolor('beige')  # 设置绘图区域的背景颜色为米色

# 定义向量a和b
vector_a = np.array([2, 3])  # 向量a的坐标
vector_b = np.array([4, 0])  # 向量b的坐标

# 绘制向量a
origin = np.array([0, 0])  # 向量的起点
ax.quiver(*origin, *vector_a, color='blue', scale_units='xy', angles='xy', scale=1, label=r'$\vec{a}$')  # 使用quiver函数绘制向量a,颜色为蓝色

# 绘制向量b
ax.quiver(*origin, *vector_b, color='teal', scale_units='xy', angles='xy', scale=1, label=r'$\vec{b}$')  # 使用quiver函数绘制向量b,颜色为蓝绿色

# 计算向量a在向量b上的投影长度
proj_length = np.dot(vector_a, vector_b) / np.linalg.norm(vector_b)  # 计算向量a在向量b上的投影长度
projection = proj_length * vector_b / np.linalg.norm(vector_b)  # 计算投影点的坐标

# 绘制投影线段
ax.plot([0, projection[0]], [0, projection[1]], linestyle='dashed', color='purple', label='Projection')  # 绘制从原点到投影点的虚线,颜色为紫色
ax.plot([vector_a[0], projection[0]], [vector_a[1], projection[1]], linestyle='dotted', color='gray', label='A to Projection')  # 绘制从点A到投影点的点划线,颜色为灰色

# 添加文本标签
ax.text(-0.3, -0.3, r'$O$', fontsize=14, color='black')  # 在原点附近添加文本标签O
ax.text(2.1, 3.1, r'$A$', fontsize=14, color='blue')  # 在点A附近添加文本标签A
ax.text(4.0, -0.3, r'$B$', fontsize=14, color='teal')  # 在点B附近添加文本标签B
ax.text(0.5, 0.3, r'$\theta$', fontsize=14, color='red')  # 在原点附近添加角度θ的标签
ax.text(1.0, -0.5, r'$|a|\cos{\theta}$', fontsize=14, color='purple')  # 在投影线段下方添加投影长度的标签

# 添加点标记
ax.scatter(projection[0], projection[1], color='purple', s=100, label='Projection Point')  # 标记投影点,颜色为紫色
ax.scatter(vector_b[0], vector_b[1], color='teal', s=100, label=r'End of $\vec{b}$')  # 标记向量b的终点,颜色为蓝绿色
ax.scatter(origin[0], origin[1], color='black', s=100, label='Origin')  # 标记原点,颜色为黑色
ax.scatter(vector_a[0], vector_a[1], color='blue', s=100, label='Point A')  # 标记点A,颜色为蓝色

# 设置坐标轴范围和隐藏坐标轴
ax.set_xlim([-1, 5])  # 设置x轴的显示范围
ax.set_ylim([-1, 4])  # 设置y轴的显示范围
ax.axis('off')  # 隐藏坐标轴

# 显示图例
ax.legend(loc='upper right')  # 在右上角显示图例

# 显示图形
plt.show()  # 显示图形

在Python字符串中,前缀 r 表示一个原始字符串(raw string)。原始字符串中的反斜杠 \ 不会被转义,而是作为普通字符处理。这对于包含反斜杠的字符串(如正则表达式或LaTeX公式)非常有用,因为这样可以避免多次转义带来的混乱。

ax.text(1.0, -0.5, r'$|a|\cos{\theta}$', fontsize=14, color='purple')

这里的 r 就是用来告诉Python解析器,这个字符串中的反斜杠 \ 是普通字符,而不是转义字符。这样,$\cos{\theta}$ 就会被正确地解析为LaTeX数学模式中的余弦函数符号。

如果不使用 r 前缀,字符串中的反斜杠会被转义,例如:

  • '\n' 会被解析为换行符。
  • '\t' 会被解析为制表符。

使用 r 前缀可以确保LaTeX公式中的反斜杠不会被错误解析,从而正确显示数学符号。

计算向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影长度和投影点的坐标

  • np.dot(vector_a, vector_b):计算向量 a ⃗ \vec{a} a b ⃗ \vec{b} b 的点积。
  • np.linalg.norm(vector_b):计算向量 b ⃗ \vec{b} b 的模。
  • proj_length:计算向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影长度。
  • projection:计算向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影向量的坐标。

1. 计算向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影长度

proj_length = np.dot(vector_a, vector_b) / np.linalg.norm(vector_b)
解释:
  • np.dot(vector_a, vector_b):这是计算向量 a ⃗ \vec{a} a 和向量 b ⃗ \vec{b} b 的点积(内积)。点积的公式是:
    a ⃗ ⋅ b ⃗ = a 1 b 1 + a 2 b 2 + ⋯ + a n b n \vec{a} \cdot \vec{b} = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n a b =a1b1+a2b2++anbn
    其中 a i a_i ai b i b_i bi 分别是向量 a ⃗ \vec{a} a b ⃗ \vec{b} b 的对应分量。

  • np.linalg.norm(vector_b):这是计算向量 b ⃗ \vec{b} b 的模(长度)。模的公式是:
    ∥ b ⃗ ∥ = b 1 2 + b 2 2 + ⋯ + b n 2 \|\vec{b}\| = \sqrt{b_1^2 + b_2^2 + \cdots + b_n^2} b =b12+b22++bn2
    np.linalg.norm 是 NumPy 库中的一个函数,用于计算向量的范数(默认是2-范数,即欧几里得距离)。

  • proj_length:这是向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影长度。根据公式:
    proj_length = a ⃗ ⋅ b ⃗ ∥ b ⃗ ∥ \text{proj\_length} = \frac{\vec{a} \cdot \vec{b}}{\|\vec{b}\|} proj_length=b a b

2. 计算投影点的坐标

projection = proj_length * vector_b / np.linalg.norm(vector_b)
解释:
  • proj_length * vector_b:这一步是将投影长度乘以向量 b ⃗ \vec{b} b 。这会得到一个与 b ⃗ \vec{b} b 方向相同的向量,但长度为 proj_length

  • / np.linalg.norm(vector_b):这一步是将上述结果除以 b ⃗ \vec{b} b 的模。这样做是为了将向量 b ⃗ \vec{b} b 归一化(即变成单位向量),从而确保投影向量的长度为 proj_length

  • projection:这是向量 a ⃗ \vec{a} a 在向量 b ⃗ \vec{b} b 上的投影向量的坐标。根据公式:
    projection = ( a ⃗ ⋅ b ⃗ ∥ b ⃗ ∥ 2 ) b ⃗ \text{projection} = \left( \frac{\vec{a} \cdot \vec{b}}{\|\vec{b}\|^2} \right) \vec{b} projection=(b 2a b )b
    这个公式可以分解为:
    projection = ( a ⃗ ⋅ b ⃗ ∥ b ⃗ ∥ ) ( b ⃗ ∥ b ⃗ ∥ ) \text{projection} = \left( \frac{\vec{a} \cdot \vec{b}}{\|\vec{b}\|} \right) \left( \frac{\vec{b}}{\|\vec{b}\|} \right) projection=(b a b )(b b )
    其中, b ⃗ ∥ b ⃗ ∥ \frac{\vec{b}}{\|\vec{b}\|} b b b ⃗ \vec{b} b 的单位向量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二分掌柜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值