基于参数化模型的砂轮轮廓建模与可视化

引言

在精密磨削加工中,砂轮的几何轮廓直接影响加工精度和表面质量。本文基于参数化建模方法,推导了具有复杂轮廓的砂轮的数学模型,并提供了完整的Python实现。该模型能够精确描述包含圆弧过渡段和锥面段的砂轮轮廓,为后续的包络计算和加工仿真奠定基础。

砂轮轮廓的数学模型

砂轮坐标系定义

砂轮坐标系 Og−XgYgZgO_g-X_gY_gZ_gOg−XgYgZg 定义如下:

  • 原点 OgO_gOg 位于砂轮端面中心
  • ZgZ_gZg 轴垂直于砂轮端面
  • XgX_gXg 和 YgY_gYg 轴位于端面内

参数化表面方程

砂轮轮廓面上任一点 WWW 在砂轮坐标系中的齐次坐标表示为:

Wg=(xg(h,θ)yg(h,θ)zg(h,θ)1)=(R(h)cos⁡θR(h)sin⁡θh1),h∈[0,H],θ∈[0,2π] W_{g} = \begin{pmatrix} x_{g}(h,\theta) \\ y_{g}(h,\theta) \\ z_{g}(h,\theta) \\ 1 \end{pmatrix} = \begin{pmatrix} R(h)\cos\theta \\ R(h)\sin\theta \\ h \\ 1 \end{pmatrix}, \quad h \in [0, H], \theta \in [0, 2\pi] Wg= xg(h,θ)yg(h,θ)zg(h,θ)1 = R(h)cosθR(h)sinθh1 ,h∈[0,H],θ∈[0,2π]

其中:

  • hhh:砂轮轮廓高度(轴向位置变量)
  • θ\thetaθ:旋转角
  • R(h)R(h)R(h):半径函数
  • HHH:砂轮宽度

半径函数的分段定义

根据 hhh 的不同取值范围,半径函数 R(h)R(h)R(h) 分段定义为:

R(h)={R−Rwl+Rwl2−(Rwl−h)2,h∈[0,hL]R(hL)−(h−hL)tan⁡κ,h∈[hL,H−hr]R(hL)−hmtan⁡κ−Rwrcos⁡κ+Rwr2−(Rwr−H+h)2,h∈[H−hr,H] R(h) = \begin{cases} R - R_{wl} + \sqrt{R_{wl}^{2} - (R_{wl} - h)^{2}}, & h \in [0, h_{L}] \\ R(h_{L}) - (h - h_{L}) \tan \kappa, & h \in [h_{L}, H - h_{r}] \\ R(h_{L}) - h_{m} \tan \kappa - R_{wr} \cos \kappa + \sqrt{R_{wr}^{2} - (R_{wr} - H + h)^{2}}, & h \in [H - h_{r}, H] \end{cases} R(h)=⎩ ⎨ ⎧R−Rwl+Rwl2−(Rwl−h)2 ,R(hL)−(h−hL)tanκ,R(hL)−hmtanκ−Rwrcosκ+Rwr2−(Rwr−H+h)2 ,h∈[0,hL]h∈[hL,H−hr]h∈[H−hr,H]

相关几何参数:

  • RRR:砂轮基本半径
  • RwlR_{wl}Rwl:左侧轮廓圆角半径
  • RwrR_{wr}Rwr:右侧轮廓圆角半径
  • hLh_{L}hL:左侧切点的轴向位置
  • hrh_{r}hr:右侧切点的轴向位置
  • hmh_{m}hm:锥面段的轴向长度
  • κ\kappaκ:砂轮锥角

角度参数与几何关系

圆弧对应的中心角与砂轮锥角的关系:

{α0=π2+κα1=π2−κ \begin{cases} \alpha_{0} = \frac{\pi}{2} + \kappa \\ \alpha_{1} = \frac{\pi}{2} - \kappa \end{cases} {α0=2π+κα1=2π−κ

左侧圆弧 CACACA 上 hhh 与 αAC\alpha_{AC}αAC 的显式关系:

h(αAC)=2Rwlsin⁡2αAC2,αAC∈[0,α0] h(\alpha_{AC}) = 2R_{wl} \sin^{2} \frac{\alpha_{AC}}{2}, \quad \alpha_{AC} \in [0, \alpha_{0}] h(αAC)=2Rwlsin22αAC,αAC∈[0,α0]

右侧圆弧 BDBDBD 的几何关系:

{hr=Rwrtan⁡α12hm=H−hL−hrh(αBD)=H−2Rwrsin⁡2αBD2,αBD∈[0,α1] \begin{cases} h_{r} = R_{wr} \tan \frac{\alpha_{1}}{2} \\ h_{m} = H - h_{L} - h_{r} \\ h(\alpha_{BD}) = H - 2R_{wr} \sin^{2} \frac{\alpha_{BD}}{2}, \quad \alpha_{BD} \in [0, \alpha_{1}] \end{cases} ⎩ ⎨ ⎧hr=Rwrtan2α1hm=H−hL−hrh(αBD)=H−2Rwrsin22αBD,αBD∈[0,α1]

完整的Python实现

代码实现:砂轮轮廓计算类

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

class GrindingWheelProfile:
    """砂轮轮廓计算与绘制类"""
    
    def __init__(self, 
                 R: float = 50.0,
                 R_wl: float = 5.0,
                 R_wr: float = 5.0,
                 H: float = 30.0,
                 kappa: float = 15.0):
        """
        初始化砂轮参数
        
        参数:
        R: 砂轮基本半径 (mm)
        R_wl: 左侧轮廓圆角半径 (mm)
        R_wr: 右侧轮廓圆角半径 (mm)
        H: 砂轮宽度 (mm)
        kappa: 砂轮锥角 (度)
        """
        # 基本参数
        self.R = R
        self.R_wl = R_wl
        self.R_wr = R_wr
        self.H = H
        self.kappa = np.deg2rad(kappa)  # 转换为弧度
        
        # 计算相关几何参数
        self._calculate_parameters()
        
    def _calculate_parameters(self):
        """计算几何参数"""
        # 公式(2-3): 计算角度参数
        self.alpha_0 = np.pi/2 + self.kappa  # 左侧圆弧最大中心角
        self.alpha_1 = np.pi/2 - self.kappa  # 右侧圆弧最大中心角
        
        # 公式(2-5): 计算左侧切点A的轴向位置h_L
        self.h_L = 2 * self.R_wl * (np.sin(self.alpha_0/2)**2)
        
        # 公式(2-6): 计算右侧切点B的轴向位置h_r和锥面段长度h_m
        self.h_r = self.R_wr * np.tan(self.alpha_1/2)
        self.h_m = self.H - self.h_L - self.h_r
        
        # 计算h=h_L处的半径值
        self.R_hL = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - self.h_L)**2)
        
    def R_h(self, h: np.ndarray) -> np.ndarray:
        """
        公式(2-2): 半径函数分段计算
        
        参数:
        h: 轴向位置数组
        
        返回:
        R: 对应半径数组
        """
        h = np.asarray(h)
        R = np.zeros_like(h)
        
        # 分段条件
        left_mask = h <= self.h_L  # 左侧圆弧段
        middle_mask = (h > self.h_L) & (h <= self.H - self.h_r)  # 锥面段
        right_mask = h > self.H - self.h_r  # 右侧圆弧段
        
        # 左侧圆弧段 (0 <= h <= h_L)
        if np.any(left_mask):
            h_left = h[left_mask]
            R[left_mask] = (self.R - self.R_wl + 
                           np.sqrt(self.R_wl**2 - (self.R_wl - h_left)**2))
        
        # 锥面段 (h_L < h <= H - h_r)
        if np.any(middle_mask):
            h_middle = h[middle_mask]
            R[middle_mask] = self.R_hL - (h_middle - self.h_L) * np.tan(self.kappa)
        
        # 右侧圆弧段 (H - h_r < h <= H)
        if np.any(right_mask):
            h_right = h[right_mask]
            term = (self.R_wr - self.H + h_right)
            R[right_mask] = (self.R_hL - self.h_m * np.tan(self.kappa) - 
                            self.R_wr * np.cos(self.kappa) +
                            np.sqrt(self.R_wr**2 - term**2))
        
        return R
    
    def parametric_surface(self, n_h: int = 100, n_theta: int = 50) -> tuple:
        """
        生成砂轮三维参数化表面
        
        参数:
        n_h: 轴向采样点数
        n_theta: 圆周方向采样点数
        
        返回:
        X, Y, Z: 三维坐标数组
        """
        # 生成参数网格
        h = np.linspace(0, self.H, n_h)
        theta = np.linspace(0, 2*np.pi, n_theta)
        h_grid, theta_grid = np.meshgrid(h, theta, indexing='ij')
        
        # 计算半径
        R_grid = self.R_h(h_grid)
        
        # 转换为直角坐标
        X = R_grid * np.cos(theta_grid)
        Y = R_grid * np.sin(theta_grid)
        Z = h_grid
        
        return X, Y, Z
    
    def profile_points(self, n_points: int = 500) -> tuple:
        """
        获取砂轮轮廓母线点
        
        参数:
        n_points: 采样点数
        
        返回:
        h_points, R_points: 轴向位置和半径数组
        """
        h_points = np.linspace(0, self.H, n_points)
        R_points = self.R_h(h_points)
        return h_points, R_points
    
    def get_key_points(self) -> dict:
        """
        获取关键特征点
        
        返回:
        key_points: 关键点字典,包含坐标点和参数
        """
        # 左侧圆弧起点C (h=0)
        C = (0, self.R - self.R_wl)
        
        # 左侧切点A (h=h_L)
        A = (self.h_L, self.R_hL)
        
        # 右侧切点B (h=H-h_r)
        h_B = self.H - self.h_r
        R_B = self.R_hL - (h_B - self.h_L) * np.tan(self.kappa)
        B = (h_B, R_B)
        
        # 右侧圆弧终点D (h=H)
        D = (self.H, self.R_h(np.array([self.H]))[0])
        
        return {
            'C': C,  # 左侧圆弧起点 (h, R)
            'A': A,  # 左侧切点 (h, R)
            'B': B,  # 右侧切点 (h, R)
            'D': D,  # 右侧圆弧终点 (h, R)
            'h_L': self.h_L,     # 左侧圆弧长度
            'h_r': self.h_r,     # 右侧圆弧长度
            'h_m': self.h_m,     # 锥面段长度
            'R_hL': self.R_hL    # 左侧切点处半径
        }

# 创建砂轮对象
wheel = GrindingWheelProfile(
    R=50.0,      # 基本半径 50mm
    R_wl=5.0,    # 左侧圆角半径 5mm
    R_wr=5.0,    # 右侧圆角半径 5mm
    H=30.0,      # 砂轮宽度 30mm
    kappa=15.0   # 锥角 15度
)

# 打印砂轮参数
print("=" * 50)
print("砂轮参数:")
print("=" * 50)
print(f"基本半径 R = {wheel.R} mm")
print(f"左侧圆角半径 R_wl = {wheel.R_wl} mm")
print(f"右侧圆角半径 R_wr = {wheel.R_wr} mm")
print(f"砂轮宽度 H = {wheel.H} mm")
print(f"锥角 κ = {np.rad2deg(wheel.kappa):.1f}°")
print(f"左侧最大中心角 α₀ = {np.rad2deg(wheel.alpha_0):.1f}°")
print(f"右侧最大中心角 α₁ = {np.rad2deg(wheel.alpha_1):.1f}°")

# 获取关键点并正确打印
key_points = wheel.get_key_points()

print("\n" + "=" * 50)
print("关键点坐标 (h, R):")
print("=" * 50)
for point_name in ['C', 'A', 'B', 'D']:
    h, R = key_points[point_name]
    print(f"点{point_name}: h = {h:.2f} mm, R = {R:.2f} mm")

print("\n" + "=" * 50)
print("特征长度:")
print("=" * 50)
print(f"左侧圆弧长度 h_L = {key_points['h_L']:.2f} mm")
print(f"右侧圆弧长度 h_r = {key_points['h_r']:.2f} mm")
print(f"锥面段长度 h_m = {key_points['h_m']:.2f} mm")
print(f"左侧切点处半径 R_hL = {key_points['R_hL']:.2f} mm")
print("=" * 50)

代码实现:二维轮廓可视化

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 重新定义GrindingWheelProfile类确保独立运行
class GrindingWheelProfile:
    def __init__(self, R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0):
        self.R = R
        self.R_wl = R_wl
        self.R_wr = R_wr
        self.H = H
        self.kappa = np.deg2rad(kappa)
        self._calculate_parameters()
    
    def _calculate_parameters(self):
        self.alpha_0 = np.pi/2 + self.kappa
        self.alpha_1 = np.pi/2 - self.kappa
        self.h_L = 2 * self.R_wl * (np.sin(self.alpha_0/2)**2)
        self.h_r = self.R_wr * np.tan(self.alpha_1/2)
        self.h_m = self.H - self.h_L - self.h_r
        self.R_hL = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - self.h_L)**2)
    
    def R_h(self, h):
        h = np.asarray(h)
        R = np.zeros_like(h)
        
        left_mask = h <= self.h_L
        middle_mask = (h > self.h_L) & (h <= self.H - self.h_r)
        right_mask = h > self.H - self.h_r
        
        if np.any(left_mask):
            h_left = h[left_mask]
            R[left_mask] = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - h_left)**2)
        
        if np.any(middle_mask):
            h_middle = h[middle_mask]
            R[middle_mask] = self.R_hL - (h_middle - self.h_L) * np.tan(self.kappa)
        
        if np.any(right_mask):
            h_right = h[right_mask]
            term = (self.R_wr - self.H + h_right)
            R[right_mask] = (self.R_hL - self.h_m * np.tan(self.kappa) - 
                            self.R_wr * np.cos(self.kappa) +
                            np.sqrt(self.R_wr**2 - term**2))
        
        return R

# 创建砂轮对象
wheel = GrindingWheelProfile(R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0)

# 获取关键点
h_L = wheel.h_L
h_r = wheel.h_r
R_hL = wheel.R_hL

# 创建图形
fig, ax = plt.subplots(figsize=(10, 6))

# 生成轮廓点
h_points = np.linspace(0, wheel.H, 500)
R_points = wheel.R_h(h_points)

# 绘制轮廓线
ax.plot(h_points, R_points, 'b-', linewidth=2, label='Grinding wheel profile')
ax.plot(h_points, -R_points, 'b--', linewidth=1, alpha=0.5)

# 绘制中心线
ax.axhline(y=0, color='k', linestyle='-', linewidth=0.5, alpha=0.3)

# 计算关键点坐标
C = (0, wheel.R - wheel.R_wl)
A = (h_L, R_hL)
h_B = wheel.H - h_r
R_B = R_hL - (h_B - h_L) * np.tan(wheel.kappa)
B = (h_B, R_B)
D = (wheel.H, wheel.R_h(np.array([wheel.H]))[0])

# 绘制关键点
key_points = {'C': C, 'A': A, 'B': B, 'D': D}
colors = {'C': 'r', 'A': 'g', 'B': 'm', 'D': 'c'}
markers = {'C': 'o', 'A': 's', 'B': '^', 'D': 'v'}

for point_name, (h, R) in key_points.items():
    ax.plot(h, R, f'{colors[point_name]}{markers[point_name]}', markersize=8, 
            label=f'Point {point_name}', markeredgecolor='k')

# 绘制不同线段
h_left = np.linspace(0, h_L, 50)
R_left = wheel.R_h(h_left)
ax.plot(h_left, R_left, 'r-', linewidth=1, alpha=0.5, label='Left arc segment')

h_mid = np.linspace(h_L, wheel.H - h_r, 50)
R_mid = wheel.R_h(h_mid)
ax.plot(h_mid, R_mid, 'g-', linewidth=2, alpha=0.7, label='Conical segment')

h_right = np.linspace(wheel.H - h_r, wheel.H, 50)
R_right = wheel.R_h(h_right)
ax.plot(h_right, R_right, 'm-', linewidth=1, alpha=0.5, label='Right arc segment')

# 设置图形属性
ax.set_xlabel('Axial position h (mm)', fontsize=12)
ax.set_ylabel('Radius R(h) (mm)', fontsize=12)
ax.set_title('Grinding Wheel Profile', fontsize=14, fontweight='bold')
ax.grid(True, alpha=0.3)
ax.legend(loc='best')
ax.axis('equal')

# 添加标注
ax.text(0.02, 0.98, f'κ = {np.rad2deg(wheel.kappa):.1f}°', 
        transform=ax.transAxes, verticalalignment='top',
        bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8))

plt.tight_layout()
plt.show()

代码实现:三维表面可视化

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

# 重新定义GrindingWheelProfile类确保独立运行
class GrindingWheelProfile:
    def __init__(self, R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0):
        self.R = R
        self.R_wl = R_wl
        self.R_wr = R_wr
        self.H = H
        self.kappa = np.deg2rad(kappa)
        self._calculate_parameters()
    
    def _calculate_parameters(self):
        self.alpha_0 = np.pi/2 + self.kappa
        self.alpha_1 = np.pi/2 - self.kappa
        self.h_L = 2 * self.R_wl * (np.sin(self.alpha_0/2)**2)
        self.h_r = self.R_wr * np.tan(self.alpha_1/2)
        self.h_m = self.H - self.h_L - self.h_r
        self.R_hL = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - self.h_L)**2)
    
    def R_h(self, h):
        h = np.asarray(h)
        R = np.zeros_like(h)
        
        left_mask = h <= self.h_L
        middle_mask = (h > self.h_L) & (h <= self.H - self.h_r)
        right_mask = h > self.H - self.h_r
        
        if np.any(left_mask):
            h_left = h[left_mask]
            R[left_mask] = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - h_left)**2)
        
        if np.any(middle_mask):
            h_middle = h[middle_mask]
            R[middle_mask] = self.R_hL - (h_middle - self.h_L) * np.tan(self.kappa)
        
        if np.any(right_mask):
            h_right = h[right_mask]
            term = (self.R_wr - self.H + h_right)
            R[right_mask] = (self.R_hL - self.h_m * np.tan(self.kappa) - 
                            self.R_wr * np.cos(self.kappa) +
                            np.sqrt(self.R_wr**2 - term**2))
        
        return R
    
    def parametric_surface(self, n_h=100, n_theta=50):
        h = np.linspace(0, self.H, n_h)
        theta = np.linspace(0, 2*np.pi, n_theta)
        h_grid, theta_grid = np.meshgrid(h, theta, indexing='ij')
        
        R_grid = self.R_h(h_grid)
        
        X = R_grid * np.cos(theta_grid)
        Y = R_grid * np.sin(theta_grid)
        Z = h_grid
        
        return X, Y, Z

# 创建砂轮对象
wheel = GrindingWheelProfile(R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0)

# 生成三维表面数据
X, Y, Z = wheel.parametric_surface(n_h=30, n_theta=20)

# 创建3D图形
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# 绘制表面
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, alpha=0.8, linewidth=0.5, antialiased=True)

# 绘制母线
h_line = np.linspace(0, wheel.H, 50)
R_line = wheel.R_h(h_line)
X_line = R_line * np.cos(0)
Y_line = R_line * np.sin(0)
Z_line = h_line
ax.plot(X_line, Y_line, Z_line, 'r-', linewidth=3, label='Profile generatrix')

# 获取关键点
h_L = wheel.h_L
h_r = wheel.h_r
R_hL = wheel.R_hL
C = (0, wheel.R - wheel.R_wl)
A = (h_L, R_hL)
h_B = wheel.H - h_r
R_B = R_hL - (h_B - h_L) * np.tan(wheel.kappa)
B = (h_B, R_B)
D = (wheel.H, wheel.R_h(np.array([wheel.H]))[0])

# 绘制关键点
key_points = {'C': C, 'A': A, 'B': B, 'D': D}
for point_name, (h, R) in key_points.items():
    X_pt = R * np.cos(0)
    Y_pt = R * np.sin(0)
    Z_pt = h
    ax.scatter(X_pt, Y_pt, Z_pt, s=50, c='k', marker='o')
    ax.text(X_pt, Y_pt, Z_pt, f' {point_name}', fontsize=10, color='k')

# 设置图形属性
ax.set_xlabel('X (mm)', fontsize=12)
ax.set_ylabel('Y (mm)', fontsize=12)
ax.set_zlabel('Axial position Z (mm)', fontsize=12)
ax.set_title('3D Surface of Grinding Wheel', fontsize=14, fontweight='bold')
ax.legend()
ax.view_init(elev=20, azim=45)

# 添加颜色条
fig.colorbar(surf, ax=ax, shrink=0.5, aspect=10, label='Height (mm)')

plt.tight_layout()
plt.show()

代码实现:参数化分析与半径函数可视化

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 重新定义GrindingWheelProfile类确保独立运行
class GrindingWheelProfile:
    def __init__(self, R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0):
        self.R = R
        self.R_wl = R_wl
        self.R_wr = R_wr
        self.H = H
        self.kappa = np.deg2rad(kappa)
        self._calculate_parameters()
    
    def _calculate_parameters(self):
        self.alpha_0 = np.pi/2 + self.kappa
        self.alpha_1 = np.pi/2 - self.kappa
        self.h_L = 2 * self.R_wl * (np.sin(self.alpha_0/2)**2)
        self.h_r = self.R_wr * np.tan(self.alpha_1/2)
        self.h_m = self.H - self.h_L - self.h_r
        self.R_hL = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - self.h_L)**2)
    
    def R_h(self, h):
        h = np.asarray(h)
        R = np.zeros_like(h)
        
        left_mask = h <= self.h_L
        middle_mask = (h > self.h_L) & (h <= self.H - self.h_r)
        right_mask = h > self.H - self.h_r
        
        if np.any(left_mask):
            h_left = h[left_mask]
            R[left_mask] = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - h_left)**2)
        
        if np.any(middle_mask):
            h_middle = h[middle_mask]
            R[middle_mask] = self.R_hL - (h_middle - self.h_L) * np.tan(self.kappa)
        
        if np.any(right_mask):
            h_right = h[right_mask]
            term = (self.R_wr - self.H + h_right)
            R[right_mask] = (self.R_hL - self.h_m * np.tan(self.kappa) - 
                            self.R_wr * np.cos(self.kappa) +
                            np.sqrt(self.R_wr**2 - term**2))
        
        return R

# 创建砂轮对象
wheel = GrindingWheelProfile(R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0)

# 获取参数
h_L = wheel.h_L
h_r = wheel.h_r
alpha_0 = wheel.alpha_0
alpha_1 = wheel.alpha_1
R_wl = wheel.R_wl
R_wr = wheel.R_wr
R_hL = wheel.R_hL
h_m = wheel.h_m
kappa = wheel.kappa
H = wheel.H

# 创建多子图
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Parametric Analysis of Grinding Wheel', fontsize=16, fontweight='bold')

# 1. 半径函数分段图
ax1 = axes[0, 0]
h = np.linspace(0, H, 500)
R = wheel.R_h(h)
ax1.plot(h, R, 'b-', linewidth=2)
ax1.axvline(x=h_L, color='r', linestyle='--', alpha=0.5, label=f'h_L={h_L:.2f}')
ax1.axvline(x=H-h_r, color='g', linestyle='--', alpha=0.5, label=f'H-h_r={H-h_r:.2f}')
ax1.set_xlabel('h (mm)')
ax1.set_ylabel('R(h) (mm)')
ax1.set_title('Radius Function Segmentation')
ax1.grid(True, alpha=0.3)
ax1.legend()

# 2. 左侧圆弧参数化
ax2 = axes[0, 1]
alpha_AC = np.linspace(0, alpha_0, 100)
h_AC = 2 * R_wl * (np.sin(alpha_AC/2)**2)  # 公式(2-5)
R_AC = wheel.R - R_wl + np.sqrt(R_wl**2 - (R_wl - h_AC)**2)
ax2.plot(alpha_AC, h_AC, 'r-', label='h(α_AC)')
ax2.plot(alpha_AC, R_AC, 'b-', label='R(α_AC)')
ax2.set_xlabel('α_AC (rad)')
ax2.set_ylabel('Value (mm)')
ax2.set_title('Left Arc Parameterization')
ax2.legend()
ax2.grid(True, alpha=0.3)

# 3. 右侧圆弧参数化
ax3 = axes[1, 0]
alpha_BD = np.linspace(0, alpha_1, 100)
h_BD = H - 2 * R_wr * (np.sin(alpha_BD/2)**2)  # 公式(2-6)
term = R_wr - H + h_BD
R_BD = (R_hL - h_m * np.tan(kappa) - R_wr * np.cos(kappa) + 
        np.sqrt(R_wr**2 - term**2))
ax3.plot(alpha_BD, h_BD, 'r-', label='h(α_BD)')
ax3.plot(alpha_BD, R_BD, 'b-', label='R(α_BD)')
ax3.set_xlabel('α_BD (rad)')
ax3.set_ylabel('Value (mm)')
ax3.set_title('Right Arc Parameterization')
ax3.legend()
ax3.grid(True, alpha=0.3)

# 4. 锥面段线性关系
ax4 = axes[1, 1]
h_mid = np.linspace(h_L, H-h_r, 100)
R_mid = R_hL - (h_mid - h_L) * np.tan(kappa)
ax4.plot(h_mid, R_mid, 'g-', linewidth=2)
ax4.set_xlabel('h (mm)')
ax4.set_ylabel('R(h) (mm)')
ax4.set_title(f'Conical Segment (κ={np.rad2deg(kappa):.1f}°)')
ax4.text(0.05, 0.95, f'Slope: -tan(κ) = {-np.tan(kappa):.3f}', 
         transform=ax4.transAxes, verticalalignment='top')
ax4.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

代码实现:不同锥角对比分析

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 定义GrindingWheelProfile类
class GrindingWheelProfile:
    def __init__(self, R=50.0, R_wl=5.0, R_wr=5.0, H=30.0, kappa=15.0):
        self.R = R
        self.R_wl = R_wl
        self.R_wr = R_wr
        self.H = H
        self.kappa = np.deg2rad(kappa)
        self._calculate_parameters()
    
    def _calculate_parameters(self):
        self.alpha_0 = np.pi/2 + self.kappa
        self.alpha_1 = np.pi/2 - self.kappa
        self.h_L = 2 * self.R_wl * (np.sin(self.alpha_0/2)**2)
        self.h_r = self.R_wr * np.tan(self.alpha_1/2)
        self.h_m = self.H - self.h_L - self.h_r
        self.R_hL = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - self.h_L)**2)
    
    def R_h(self, h):
        h = np.asarray(h)
        R = np.zeros_like(h)
        
        left_mask = h <= self.h_L
        middle_mask = (h > self.h_L) & (h <= self.H - self.h_r)
        right_mask = h > self.H - self.h_r
        
        if np.any(left_mask):
            h_left = h[left_mask]
            R[left_mask] = self.R - self.R_wl + np.sqrt(self.R_wl**2 - (self.R_wl - h_left)**2)
        
        if np.any(middle_mask):
            h_middle = h[middle_mask]
            R[middle_mask] = self.R_hL - (h_middle - self.h_L) * np.tan(self.kappa)
        
        if np.any(right_mask):
            h_right = h[right_mask]
            term = (self.R_wr - self.H + h_right)
            R[right_mask] = (self.R_hL - self.h_m * np.tan(self.kappa) - 
                            self.R_wr * np.cos(self.kappa) +
                            np.sqrt(self.R_wr**2 - term**2))
        
        return R

# 创建不同锥角的砂轮对象
wheels = [
    GrindingWheelProfile(R=50, R_wl=5, R_wr=5, H=30, kappa=0),   # 无锥角
    GrindingWheelProfile(R=50, R_wl=5, R_wr=5, H=30, kappa=15),  # 中锥角
    GrindingWheelProfile(R=50, R_wl=5, R_wr=5, H=30, kappa=30)   # 大锥角
]

titles = ['No Taper (κ=0°)', 'Medium Taper (κ=15°)', 'Large Taper (κ=30°)']

# 创建对比图
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
fig.suptitle('Comparison of Grinding Wheel Profiles with Different Taper Angles', 
             fontsize=14, fontweight='bold')

for ax, wheel, title in zip(axes, wheels, titles):
    # 生成轮廓点
    h_points = np.linspace(0, wheel.H, 500)
    R_points = wheel.R_h(h_points)
    
    # 绘制轮廓线
    ax.plot(h_points, R_points, 'b-', linewidth=2)
    ax.plot(h_points, -R_points, 'b--', linewidth=1, alpha=0.5)
    
    # 绘制中心线
    ax.axhline(y=0, color='k', linestyle='-', linewidth=0.5, alpha=0.3)
    
    # 获取关键点
    h_L = wheel.h_L
    h_r = wheel.h_r
    R_hL = wheel.R_hL
    
    # 计算关键点
    C = (0, wheel.R - wheel.R_wl)
    A = (h_L, R_hL)
    h_B = wheel.H - h_r
    R_B = R_hL - (h_B - h_L) * np.tan(wheel.kappa)
    B = (h_B, R_B)
    D = (wheel.H, wheel.R_h(np.array([wheel.H]))[0])
    
    # 绘制关键点
    key_points = [C, A, B, D]
    point_names = ['C', 'A', 'B', 'D']
    colors = ['r', 'g', 'm', 'c']
    
    for (h, R), name, color in zip(key_points, point_names, colors):
        ax.plot(h, R, f'{color}o', markersize=6, markeredgecolor='k')
        ax.text(h, R+1, name, fontsize=9, ha='center')
    
    ax.set_title(title)
    ax.grid(True, alpha=0.3)
    ax.axis('equal')
    
    # 添加参数信息
    info_text = f"""
    h_L = {h_L:.2f} mm
    h_r = {h_r:.2f} mm
    h_m = {wheel.h_m:.2f} mm
    α₀ = {np.rad2deg(wheel.alpha_0):.1f}°
    α₁ = {np.rad2deg(wheel.alpha_1):.1f}°
    """
    ax.text(0.05, 0.95, info_text, transform=ax.transAxes, fontsize=8,
            verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

# 设置公共标签
for ax in axes:
    ax.set_xlabel('Axial position h (mm)')
axes[0].set_ylabel('Radius R(h) (mm)')

plt.tight_layout()
plt.show()

# 打印对比数据
print("=" * 70)
print("Comparison of Parameters for Different Taper Angles")
print("=" * 70)
print(f"{'Taper Angle':<15} {'α₀ (°)':<10} {'α₁ (°)':<10} {'h_L (mm)':<12} {'h_r (mm)':<12} {'h_m (mm)':<12}")
print("-" * 70)

for wheel, title in zip(wheels, titles):
    print(f"{title:<15} {np.rad2deg(wheel.alpha_0):<10.1f} {np.rad2deg(wheel.alpha_1):<10.1f} "
          f"{wheel.h_L:<12.2f} {wheel.h_r:<12.2f} {wheel.h_m:<12.2f}")

print("=" * 70)

分析与讨论

数学模型的有效性验证

通过Python实现,我们验证了砂轮轮廓参数化模型的有效性。半径函数 R(h)R(h)R(h) 的分段定义能够精确描述包含圆弧过渡段和锥面段的复杂轮廓。关键特征点 CCC、AAA、BBB、DDD 的计算结果与几何预期一致。

参数敏感性分析

从不同锥角的对比分析可以看出:

  1. 锥角 κ\kappaκ 的影响 :随着 κ\kappaκ 增大,左侧最大中心角 α0\alpha_0α0 增大,右侧最大中心角 α1\alpha_1α1 减小,锥面段斜率绝对值增大。
  2. 圆弧段长度变化 :锥角增大导致左侧圆弧段长度 hLh_LhL 增加,右侧圆弧段长度 hrh_rhr 减小,锥面段长度 hmh_mhm 相应变化。
  3. 轮廓形状变化:无锥角时,砂轮轮廓近似为带圆角的圆柱;随着锥角增大,轮廓逐渐变为锥形。

计算精度与效率

通过自适应参数化方法,将圆弧段用中心角 α\alphaα 作为离散控制参数,可以提高包络计算的精度。半径函数的分段定义使得计算具有 O(1)O(1)O(1) 的时间复杂度,适合实时计算和仿真应用。

结论

本文建立了完整的砂轮轮廓参数化数学模型,并提供了Python实现。模型能够精确描述包含圆弧过渡段和锥面段的复杂砂轮轮廓,为精密磨削加工中的包络计算、刀具轨迹规划和加工仿真提供了理论基础和计算工具。

相关推荐
秋邱2 小时前
Java匿名内部类的使用场景:从语法本质到实战优化全解析
android·java·开发语言·数据库·python
kimi-2222 小时前
Transformer 模型中位置编码(Positional Encoding, PE)
pytorch·python·transformer
reasonsummer2 小时前
【教学类-89-02】20251229新年篇11—— 马年红包(Python图片)
python·通义万相
Mqh1807622 小时前
day53 预训练模型CBAM注意力
python
程序员佳佳2 小时前
【硬核实测】GPT-5.2-Pro 对决 Gemini-3-Pro (Banana Pro):开发者如何低成本接入下一代 AI 模型?附 Python 源码
人工智能·python·gpt·chatgpt·ai作画·midjourney·ai编程
努力变大白2 小时前
Python多指标综合评价及预测方法实战:CRITIC法+熵权法+TOPSIS+博弈论组合赋权综合评价预测全流程解析
开发语言·python
非自律懒癌患者2 小时前
‘module1 is module2‘ VS ‘module1 == module2‘
python·深度学习·计算机视觉
郝学胜-神的一滴2 小时前
李航《机器学习方法》全面解析与高效学习指南
人工智能·python·算法·机器学习·数学建模·scikit-learn
龙腾AI白云3 小时前
深度学习—卷积神经网络(1)
python·深度学习·神经网络