使用Delaunay三角剖分绘制两不等式交集区域时构建异常问题
问题分析与修复方案
原代码意图通过Delaunay三角剖分绘制两个不等式的交集区域,但存在核心问题导致剖分无法正确工作,以下是问题梳理与修复方案:
主要问题点
- 不等式判断逻辑颠倒:输入要求第一个不等式为
F(x,y) > 0、第二个为F(x,y) < 0,但代码中判断条件写为inequality1_result[j, i] < 0 and inequality2_result[j, i] > 0,直接筛选出不符合要求的区域点。 - 冗余网格点破坏均匀性:
x_vals中硬拼接了[0],若输入的x区间不包含0,会引入无效点,打乱网格的均匀分布。 - 密集网格点导致剖分混乱:直接用400×400网格中满足条件的点做Delaunay剖分,点数量可达数万,不仅计算效率低,还会让三角网图形杂乱,无法清晰展示区域轮廓。
修复后的代码
针对上述问题调整逻辑、优化网格生成,并增强可视化效果:
import numpy as np import matplotlib.pyplot as plt from sympy import symbols, sympify, lambdify, solve from scipy.spatial import Delaunay def plot_inequalities(inequality1, inequality2, x_min, x_max, y_min, y_max): x, y = symbols('x y') # 解析不等式表达式 try: inequality1_expr = sympify(inequality1) inequality2_expr = sympify(inequality2) except Exception as e: print(f"Error: 不等式格式错误 - {str(e)}") return # 转换为numpy可执行函数 try: F1 = lambdify((x, y), inequality1_expr, 'numpy') F2 = lambdify((x, y), inequality2_expr, 'numpy') except Exception as e: print(f"Error: 编译不等式失败 - {str(e)}") return # 生成均匀网格(移除冗余的[0]) x_vals = np.linspace(x_min, x_max, 200) y_vals = np.linspace(y_min, y_max, 200) X, Y = np.meshgrid(x_vals, y_vals) # 正确筛选满足两个不等式的点 mask = (F1(X, Y) > 0) & (F2(X, Y) < 0) intersection_points = np.column_stack((X[mask], Y[mask])) # Delaunay三角剖分与绘制 if len(intersection_points) >= 3: tri = Delaunay(intersection_points) # 绘制三角网轮廓 plt.triplot(intersection_points[:, 0], intersection_points[:, 1], tri.simplices, color='gray', linewidth=0.5) # 填充交集区域(可选,增强直观性) plt.tripcolor(intersection_points[:, 0], intersection_points[:, 1], tri.simplices, facecolor='lightblue', alpha=0.5) # 绘制不等式边界曲线 x_bound = np.linspace(x_min, x_max, 200) # 求解第一个不等式的边界(F1=0) sol1 = solve(inequality1_expr, y)[0] F_bound1 = lambdify(x, sol1, 'numpy') y_bound1 = F_bound1(x_bound) # 求解第二个不等式的边界(F2=0) sol2 = solve(inequality2_expr, y)[0] F_bound2 = lambdify(x, sol2, 'numpy') y_bound2 = F_bound2(x_bound) plt.plot(x_bound, y_bound1, color='red', label=f"{inequality1} 边界") plt.plot(x_bound, y_bound2, color='blue', label=f"{inequality2} 边界") # 图形基础设置 plt.xlabel('x') plt.ylabel('y') plt.grid(True, alpha=0.3) plt.axis('equal') plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) plt.legend() plt.show() # 用户输入交互 print("输入第一个不等式(格式:F(x,y) > 0):") inequality1 = input().strip() print("输入第二个不等式(格式:F(x,y) < 0):") inequality2 = input().strip() print("输入x区间(格式:x_min, x_max):") x_min, x_max = map(float, input().strip().split(',')) print("输入y区间(格式:y_min, y_max):") y_min, y_max = map(float, input().strip().split(',')) plot_inequalities(inequality1, inequality2, x_min, x_max, y_min, y_max)
修复说明
- 修正判断逻辑:将条件改为
(F1(X, Y) > 0) & (F2(X, Y) < 0),与输入要求的不等式格式匹配。 - 优化网格生成:移除冗余的
[0],生成均匀的x/y网格,避免无效点干扰。 - 高效提取点集:利用numpy布尔掩码直接筛选满足条件的点,替代嵌套循环,提升运行效率。
- 增强可视化:添加边界曲线绘制和区域填充,让交集区域更清晰;同时缩小网格密度(从400改为200),减少剖分点数量,避免图形混乱。
- 完善错误提示:捕获异常并输出具体错误信息,便于调试排查。
测试示例:输入y - x > 0和y - x**2 < 0,x区间0, 2,y区间0, 2,即可正确展示两条曲线之间的交集区域。
内容的提问来源于stack exchange,提问作者Mosh Tumuch
相关产品推荐
相关产品推荐

