You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现L1与L∞度量下两点间平分线的绘制需求

嘿,这个问题我之前做计算几何可视化的时候也遇到过!带绝对值和max的方程确实没法直接用y=ax+b这种直线公式来绘制,但咱们有两种靠谱的方案可以搞定——一种是分区域拆解方程,精确绘制分段线性的平分线,另一种是数值采样点集,快速验证并绘制。下面给你详细拆解,附Python代码示例:

方案一:分区域拆解方程(精确绘制)

这种方法的核心是去掉绝对值和max函数,把原方程拆成多个带约束的线性方程,每个方程对应平面上的一个区域,然后绘制每个区域内符合条件的线段。

1. L₁度量(曼哈顿距离)的平分线

你的方程是:|x-x₁| + |y-y₁| = |x-x₂| + |y-y₂|,整理后可以拆成两条互相垂直的直线:

  • x + y = (x₁ + y₁ + x₂ + y₂)/2
  • x - y = (x₁ - y₁ + x₂ - y₂)/2

所有满足原方程的点都在这两条直线上,直接绘制即可覆盖全部平分线区域。

2. L∞度量(切比雪夫距离)的平分线

你的方程是:max(|x-x₁|, |y-y₁|) = max(|x-x₂|, |y-y₂|),可以拆成四种带约束的情况:

  1. 当|x-x₁| ≥ |y-y₁|且|x-x₂| ≥ |y-y₂|:方程简化为x = (x₁+x₂)/2,仅在y的范围[y₁ - |(x₂-x₁)/2|, y₁ + |(x₂-x₁)/2|]内有效
  2. 当|x-x₁| ≥ |y-y₁|且|x-x₂| < |y-y₂|:方程变为|x-x₁| = |y-y₂|,对应两条直线y = x - (x₁ - y₂)和y = -x + (x₁ + y₂),需筛选满足约束的线段
  3. 当|x-x₁| < |y-y₁|且|x-x₂| ≥ |y-y₂|:方程变为|y-y₁| = |x-x₂|,对应两条直线y = x + (y₁ - x₂)和y = -x + (y₁ + x₂),需筛选满足约束的线段
  4. 当|x-x₁| < |y-y₁|且|x-x₂| < |y-y₂|:方程简化为y = (y₁+y₂)/2,仅在x的范围[x₁ - |(y₂-y₁)/2|, x₁ + |(y₂-y₁)/2|]内有效

把这些线段组合起来,就是L∞度量下的完整平分线。

方案二:数值采样法(快速实现)

如果不想花时间推导分段方程,数值采样是个偷懒但有效的方法:生成大量的(x,y)点,判断每个点是否满足平分线方程(可以加一个微小的误差容忍,比如abs(left_side - right_side) < 1e-3),然后把符合条件的点收集起来绘制。

Python代码示例(两种方案结合)

import matplotlib.pyplot as plt
import numpy as np

# 定义两点坐标
x1, y1 = 0, 0
x2, y2 = 3, 2

# --------------------------
# 方案一:精确绘制L1和L∞平分线
# --------------------------
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# L1度量平分线
l1_line1 = lambda x: (x1 + y1 + x2 + y2)/2 - x
l1_line2 = lambda x: x - (x1 - y1 + x2 - y2)/2

x_l1 = np.linspace(min(x1, x2)-2, max(x1, x2)+2, 100)
ax1.plot(x_l1, l1_line1(x_l1), label='L1 平分线1', color='red')
ax1.plot(x_l1, l1_line2(x_l1), label='L1 平分线2', color='blue')
ax1.scatter([x1, x2], [y1, y2], color='black', s=50)
ax1.set_title('L₁度量下的两点平分线')
ax1.legend()
ax1.grid(True)

# L∞度量平分线
dx = x2 - x1
dy = y2 - y1
mid_x = (x1 + x2)/2
mid_y = (y1 + y2)/2

# 情况1:x=mid_x,满足约束
y_range1 = np.linspace(y1 - abs(dx/2), y1 + abs(dx/2), 100)
ax2.plot([mid_x]*len(y_range1), y_range1, color='red', label='L∞ 线段1')

# 情况4:y=mid_y,满足约束
x_range4 = np.linspace(x1 - abs(dy/2), x1 + abs(dy/2), 100)
ax2.plot(x_range4, [mid_y]*len(x_range4), color='blue', label='L∞ 线段4')

# 情况2:|x-x1|=|y-y2|,筛选约束点
x_range2 = np.linspace(min(x1, x2)-2, max(x1, x2)+2, 100)
y2_1 = x_range2 - (x1 - y2)
y2_2 = -x_range2 + (x1 + y2)
mask2_1 = (abs(x_range2 - x1) >= abs(y2_1 - y1)) & (abs(x_range2 - x2) < abs(y2_1 - y2))
mask2_2 = (abs(x_range2 - x1) >= abs(y2_2 - y1)) & (abs(x_range2 - x2) < abs(y2_2 - y2))
ax2.plot(x_range2[mask2_1], y2_1[mask2_1], color='green', label='L∞ 线段2')
ax2.plot(x_range2[mask2_2], y2_2[mask2_2], color='green')

# 情况3:|y-y1|=|x-x2|,筛选约束点
y3_1 = x_range2 + (y1 - x2)
y3_2 = -x_range2 + (y1 + x2)
mask3_1 = (abs(x_range2 - x1) < abs(y3_1 - y1)) & (abs(x_range2 - x2) >= abs(y3_1 - y2))
mask3_2 = (abs(x_range2 - x1) < abs(y3_2 - y1)) & (abs(x_range2 - x2) >= abs(y3_2 - y2))
ax2.plot(x_range2[mask3_1], y3_1[mask3_1], color='orange', label='L∞ 线段3')
ax2.plot(x_range2[mask3_2], y3_2[mask3_2], color='orange')

ax2.scatter([x1, x2], [y1, y2], color='black', s=50)
ax2.set_title('L∞度量下的两点平分线')
ax2.legend()
ax2.grid(True)

# --------------------------
# 方案二:数值采样法示例(L1)
# --------------------------
fig2, ax3 = plt.subplots(figsize=(6,5))
x_sample = np.linspace(min(x1,x2)-3, max(x1,x2)+3, 500)
y_sample = np.linspace(min(y1,y2)-3, max(y1,y2)+3, 500)
X, Y = np.meshgrid(x_sample, y_sample)

l1_diff = abs(X - x1) + abs(Y - y1) - (abs(X - x2) + abs(Y - y2))
mask = abs(l1_diff) < 1e-3
ax3.scatter(X[mask], Y[mask], s=1, color='purple', label='L1 采样点')
ax3.scatter([x1, x2], [y1, y2], color='black', s=50)
ax3.set_title('数值采样法绘制L₁平分线')
ax3.legend()
ax3.grid(True)

plt.tight_layout()
plt.show()
补充说明
  • 方案一的精确绘制需要注意约束条件,否则会画出超出有效区域的线段,代码里已经通过mask做了筛选;
  • 方案二的采样密度可以通过调整linspace的点数来控制,点数越多精度越高,但计算量也会增加;
  • 如果你需要处理特殊情况(比如两点重合、在同一水平线/垂直线上),可以在代码里添加判断分支做特殊处理。

内容的提问来源于stack exchange,提问作者gaganso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:32:15