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

Python实现多控制点直纹曲面(Ruled surface)技术求助

扩展直纹曲面至多点/多轮廓线的实现方案

核心思路

直纹曲面的核心是在多条轮廓曲线的对应参数点之间做线性插值,而非原代码中的双线性曲面插值。我们需要实现以下几点:

  • 支持输入任意数量的轮廓曲线(每条曲线由3D点序列或参数方程定义)
  • 对每条曲线上同一参数位置的点,按权重插值生成曲面上的点
  • 优化绘图逻辑,适配多轮廓线的展示

修改后的完整代码

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

# 定义多条轮廓曲线(可替换为用户输入的点序列)
def get_contour_curves(num_points_per_curve=50):
    t = np.linspace(0, 2*np.pi, num_points_per_curve)
    # 轮廓曲线1:螺旋线
    curve1 = np.array([np.cos(t), np.sin(t), t/3]).T
    # 轮廓曲线2:变形螺旋线
    curve2 = np.array([1.5*np.cos(t), np.sin(t)+0.5, t/3 + np.cos(t)/2]).T
    # 轮廓曲线3:椭圆线
    curve3 = np.array([2*np.cos(t), 0.8*np.sin(t), np.zeros_like(t)]).T
    # 返回轮廓曲线列表
    return [curve1, curve2, curve3]

# 生成直纹曲面上的点
def generate_ruled_surface(contours, w_steps=50):
    # w是轮廓曲线之间的插值参数,范围0到1
    w = np.linspace(0, 1, w_steps)
    num_curves = len(contours)
    surface_points = []
    
    # 遍历每个参数位置t(对应每条曲线上的点索引)
    for t_idx in range(len(contours[0])):
        # 获取所有轮廓曲线在当前t位置的点
        curve_points = [contour[t_idx] for contour in contours]
        # 在轮廓曲线之间做线性插值
        for w_val in w:
            if num_curves == 2:
                # 两条曲线的情况:直接线性插值
                point = (1 - w_val) * curve_points[0] + w_val * curve_points[1]
            else:
                # 多条曲线的情况:分段线性插值
                segment_idx = int(w_val * (num_curves - 1))
                segment_w = (w_val * (num_curves - 1)) % 1
                point = (1 - segment_w) * curve_points[segment_idx] + segment_w * curve_points[segment_idx + 1]
            surface_points.append(point)
    
    return np.array(surface_points), w

# 3D曲面绘图函数
def plot_ruled_surface(surface_points, contours):
    fig = plt.figure(figsize=(8, 8))
    ax = fig.add_subplot(projection='3d')
    
    # 绘制曲面点云
    ax.scatter(surface_points[:, 0], surface_points[:, 1], surface_points[:, 2], 
               color='#7379ff', alpha=0.2, s=5)
    
    # 绘制原始轮廓曲线
    colors = ['#484167', '#ff6b6b', '#198754']
    for idx, contour in enumerate(contours):
        ax.scatter(contour[:, 0], contour[:, 1], contour[:, 2], 
                   color=colors[idx % len(colors)], alpha=0.8, s=10, label=f'轮廓曲线{idx+1}')
    
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.legend()
    plt.show()

# 投影绘图函数
def plot_projections(surface_points):
    fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(4, 10))
    
    ax1.scatter(surface_points[:, 1], surface_points[:, 2], c=surface_points[:, 2], 
                cmap='Purples', zorder=3, s=2)
    ax2.scatter(surface_points[:, 0], surface_points[:, 2], c=surface_points[:, 2], 
                cmap='Purples', zorder=3, s=2)
    ax3.scatter(surface_points[:, 0], surface_points[:, 1], c=surface_points[:, 2], 
                cmap='Purples', zorder=3, s=2)
    
    ax1.grid(zorder=0)
    ax2.grid(zorder=0)
    ax3.grid(zorder=0)
    
    ax1.set_xlabel('Y')
    ax1.set_ylabel('Z')
    ax2.set_xlabel('X')
    ax2.set_ylabel('Z')
    ax3.set_xlabel('X')
    ax3.set_ylabel('Y')
    
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    # 获取轮廓曲线(可替换为用户输入的点序列)
    contour_curves = get_contour_curves()
    # 生成直纹曲面
    surface_points, w_params = generate_ruled_surface(contour_curves)
    # 绘图
    plot_ruled_surface(surface_points, contour_curves)
    plot_projections(surface_points)

关键修改说明

  • 轮廓曲线定义:替换原代码的固定4点结构,改为支持任意数量的3D轮廓曲线,每条曲线可由参数方程或用户输入的点序列生成
  • 直纹曲面生成:核心逻辑改为在多条轮廓曲线的对应点之间做线性插值,同时支持2条或多条曲线的平滑过渡
  • 绘图优化:新增轮廓曲线的标注区分,清晰展示原始曲线与生成的曲面点,提升可视化效果
  • 灵活性提升:用户只需替换get_contour_curves函数内容,即可导入自定义点序列作为轮廓曲线

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:17:08