python求解离散曲线生成的螺旋面与平面的交线

1、螺旋运动简介

螺旋运动是一种特殊的运动形式,它同时包含了旋转和直线运动的元素。在螺旋运动中,物体沿着一个固定点周围旋转,并且随着时间的推移,沿着旋转方向上下移动。

以三维空间为例,可以将螺旋运动想象成沿着一个垂直轴向上升或向下降,并且同时围绕着这个轴心点旋转。当观察者从一个固定视角观察时,物体的轨迹呈现出一种类似于螺旋形状的运动。

螺旋运动具有以下特征:

旋转:物体围绕某个固定点以一定的角速度旋转。在三维空间中,可以采用圆周运动的方式来描述旋转部分。

直线运动:物体随着时间的流逝,沿着旋转轴向上升或向下降。

螺旋运动可以在多个领域中被观察到,例如天文学中的星系旋转、流体力学中的涡旋运动以及自然界中的一些生物运动。在工程和技术应用中,螺旋运动也有广泛的应用,比如螺旋桨、螺旋电动机等。

2、已知曲线数据

import sympy as sy
import numpy as np
import matplotlib.pyplot as plt
import time
start=time.perf_counter()
pr={"theta_value":10*np.pi/180,"R":0.506/2,"delta0":40*np.pi/180,"rotate_blank":0*np.pi/180}
def openreadtxt(file_name):
    data = []
    with open(file_name, 'r') as file:
        file_data = file.readlines()  # 读取所有行
        for row in file_data:
            tmp_list = row.split('\n')  # 去掉换行符
            tmp_list = row.split(',')
            tmp = [float(x) for x in tmp_list]
            data.append(tmp)  # 将每行数据插入data中
    return data


filename1 = r"0.506_0.88_-0.0817_0_delta40_lamda_40_1.txt"
data = openreadtxt(filename1)
X = np.array(data)[:, 0]
Y = np.array(data)[:, 1]

end = time.perf_counter()
execution_time = end - start
print(f"代码执行时间:{execution_time}秒")

# plt.show()
fig = plt.figure(figsize=(5, 5))
plt.rcParams['xtick.direction'] = 'in'  # 将x周的刻度线方向设置向内
plt.rcParams['ytick.direction'] = 'in'  # 将y轴的刻度方向设置向内
clist = ['blue', 'red', 'green', 'black', 'darkgreen', 'lime', 'gold', 'purple', 'green', 'cyan', 'salmon', 'grey',
             'mediumvioletred', 'darkkhaki', 'gray', 'darkcyan', 'violet', 'powderblue']
# ==========================================
# 参数方程画料棒圆形
theta_blank = np.arange(0, 2 * np.pi, 0.01)
x_blank = 0 + pr["R"] * np.cos(theta_blank)
y_blank = 0 + pr["R"] * np.sin(theta_blank)
plt.plot(x_blank, y_blank, c=clist[0])
#draw contour data
plt.scatter(Y,X,label="curve data")
plt.legend()
plt.tight_layout()
plt.show()

3、螺旋面建模及绘制

import sympy as sy
import numpy as np
from scipy.optimize import brentq
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
import time
start=time.perf_counter()

def openreadtxt(file_name):
    data = []
    with open(file_name, 'r') as file:
        file_data = file.readlines()  # 读取所有行
        for row in file_data:
            tmp_list = row.split('\n')  # 去掉换行符
            tmp_list = row.split(',')
            tmp = [float(x) for x in tmp_list]
            data.append(tmp)  # 将每行数据插入data中
    return data
filename1=r"1.txt"
data=openreadtxt(filename1)
X=np.array(data)[:,0]
Y=np.array(data)[:,1]

f1, f2, R, delta0, vw = sy.symbols('f1 f2 R delta0 vw')
rw = sy.Matrix([f1, f2, 0])
k = R / sy.tan(delta0)
WtoF = sy.Matrix([[sy.cos(vw), -sy.sin(vw), 0], [sy.sin(vw), sy.cos(vw), 0], [0, 0, 1]])
Trans1 = sy.Matrix([0, 0, k * vw])
Rf_expr = WtoF * rw + Trans1
Rf_fn = sy.lambdify((f1, f2, R, delta0, vw), Rf_expr)

vw_range = np.linspace(0, 2 * np.pi, 100)  # vw的范围,将其分成100个等间隔点

Rf_values = []

for x, y in zip(X, Y):
    Rf = Rf_fn(x, y, 0.5, np.pi / 4, vw_range)
    Rf_values.append(Rf)

Rf_values = np.array(Rf_values).squeeze()

end = time.perf_counter()
execution_time = end - start
print(f"代码执行时间:{execution_time}秒")
# 显示螺旋面
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

for Rf in Rf_values:
    ax.plot(Rf[0,:], Rf[1,:], Rf[2,:])

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

图片

4、平面建模及绘制

import sympy as sy
import numpy as np
import matplotlib.pyplot as plt

# 定义符号和角度
x, y, z, theta = sy.symbols('x y z theta')
theta_value = np.radians(30)  # 将角度转换为弧度

# 定义平面方程
plane_eq = sy.Eq(z, y * sy.tan(theta))

# 代入x和y变量,计算出z值
Z_func = sy.lambdify((x, y), plane_eq.rhs.subs({theta: theta_value}))
X = np.linspace(0, 2*np.pi, 100)
Y = np.linspace(0, 2*np.pi, 100)
X, Y = np.meshgrid(X, Y)
Z = Z_func(X, Y)

# 绘制平面图形
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 绘制平面
ax.plot_surface(X, Y, Z, alpha=0.5)

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

图片

5、由原始曲线数据求螺旋面与平面交线在XOY面的投影

import sympy as sy
import numpy as np
import matplotlib.pyplot as plt
import time
start=time.perf_counter()
pr={"theta_value":10*np.pi/180,"R":0.506/2,"delta0":40*np.pi/180,"rotate_blank":0*np.pi/180}
def openreadtxt(file_name):
    data = []
    with open(file_name, 'r') as file:
        file_data = file.readlines()  # 读取所有行
        for row in file_data:
            tmp_list = row.split('\n')  # 去掉换行符
            tmp_list = row.split(',')
            tmp = [float(x) for x in tmp_list]
            data.append(tmp)  # 将每行数据插入data中
    return data


filename1 = r"0.506_0.88_-0.0817_0_delta40_lamda_40_1.txt"
data = openreadtxt(filename1)
X = np.array(data)[:, 0]*np.cos(pr["rotate_blank"])+np.array(data)[:, 1]*np.sin(pr["rotate_blank"])
Y = -np.array(data)[:, 0]*np.sin(pr["rotate_blank"])+np.array(data)[:, 1]*np.cos(pr["rotate_blank"])

# 定义符号和角度
f1, f2, R, delta0, vw = sy.symbols('f1 f2 R delta0 vw')
rw = sy.Matrix([f1, f2, 0])
k = R / sy.tan(delta0)
WtoF = sy.Matrix([[sy.cos(vw), -sy.sin(vw), 0], [sy.sin(vw), sy.cos(vw), 0], [0, 0, 1]])
Trans1 = sy.Matrix([0, 0, k * vw])
Rf_expr = WtoF * rw + Trans1

x, y, z, theta = sy.symbols('x y z theta')

# 定义平面方程
plane_eq = sy.Eq(z, y * sy.tan(theta))

# 计算交点

f_intersect=Rf_expr[2]-Rf_expr[1]*sy.tan(theta)
f_intersect_fn=sy.lambdify((f1, f2, R, delta0, vw,theta), f_intersect)

vw_range = np.linspace(0, 2 * np.pi, 1000)  # vw的范围,将其分成1000个等间隔点
vw_coll=[]
for xi, yi in zip(X, Y):
    ffn = f_intersect_fn(xi, yi, pr["R"], pr["delta0"], vw_range,pr["theta_value"])
    pos=np.argmin(np.abs(ffn))
    vw_coll.append(vw_range[pos])

Rf_fn = sy.lambdify((f1, f2, R, delta0, vw), Rf_expr)

Rf_intersect = []

for xi, yi,vi in zip(X, Y,vw_coll):
    if vi==0:
        continue
    Rf = Rf_fn(xi, yi, pr["theta_value"], pr["delta0"], vi)
    Rf_intersect.append(Rf)

Rf_intersect = np.array(Rf_intersect).squeeze()
#计算螺旋面坐标
Rf_values = []
for xi, yi in zip(X, Y):
    Rf = Rf_fn(xi, yi, pr["theta_value"], pr["delta0"], vw_range)
    Rf_values.append(Rf)

Rf_values = np.array(Rf_values).squeeze()


#计算平面坐标
# 代入x和y变量,计算出z值
Z_func = sy.lambdify((x, y), plane_eq.rhs.subs({theta: pr["theta_value"]}),"numpy")
X_p = np.linspace(-pr["R"], pr["R"], 100)
Y_p = np.linspace(-pr["R"],pr["R"], 100)
X_p, Y_p = np.meshgrid(X_p, Y_p)
Z_p = Z_func(X_p, Y_p)





end = time.perf_counter()
execution_time = end - start
print(f"代码执行时间:{execution_time}秒")

# fig = plt.figure()
# ax = fig.add_subplot(111, projection='3d')
# # 绘制交线
# ax.plot(Rf_intersect[:,0], Rf_intersect[:,1], Rf_intersect[:,2],'r*')
# # 绘制螺旋面
# for Rf in Rf_values:
#     ax.plot(Rf[0,:], Rf[1,:], Rf[2,:])
# # 绘制平面
# ax.plot_surface(X_p, Y_p, Z_p)
# ax.set_xlabel('X')
# ax.set_ylabel('Y')
# ax.set_zlabel('Z')
#
# plt.show()
fig = plt.figure(figsize=(5, 5))
plt.rcParams['xtick.direction'] = 'in'  # 将x周的刻度线方向设置向内
plt.rcParams['ytick.direction'] = 'in'  # 将y轴的刻度方向设置向内
clist = ['blue', 'red', 'green', 'black', 'darkgreen', 'lime', 'gold', 'purple', 'green', 'cyan', 'salmon', 'grey',
             'mediumvioletred', 'darkkhaki', 'gray', 'darkcyan', 'violet', 'powderblue']
# ==========================================
# 参数方程画料棒圆形
theta_blank = np.arange(0, 2 * np.pi, 0.01)
x_blank = 0 + pr["R"] * np.cos(theta_blank)
y_blank = 0 + pr["R"] * np.sin(theta_blank)
plt.plot(x_blank, y_blank, c=clist[0])
#draw contour data
plt.scatter(Y,X,label="curve data")
#draw primary face data
plt.scatter(Rf_intersect[:,1],Rf_intersect[:,0],label="intersect on xoy")
plt.legend()
plt.tight_layout()
plt.show()

6、由螺旋面与平面交线在XOY面的投影求原始曲线

6.1先保存交线的投影:

def save_points_to_file(Point_x,Point_y, filename):
    with open(filename, 'w') as file:
        for i in range(len(Point_x)):
            x, y, z = Point_x[i],Point_y[i],0.0
            file.write(f"{x},{y},{z}\n")
filename2="intersect on xoy.txt"
save_points_to_file(Rf_intersect[:,0],Rf_intersect[:,1],filename2)

6.3由投影求原始曲线

import sympy as sy
import numpy as np
import matplotlib.pyplot as plt
import time
start=time.perf_counter()
pr={"theta_value":10*np.pi/180,"R":0.506/2,"delta0":40*np.pi/180,"rotate_blank":0*np.pi/180}
def openreadtxt(file_name):
    data = []
    with open(file_name, 'r') as file:
        file_data = file.readlines()  # 读取所有行
        for row in file_data:
            tmp_list = row.split('\n')  # 去掉换行符
            tmp_list = row.split(',')
            tmp = [float(x) for x in tmp_list]
            data.append(tmp)  # 将每行数据插入data中
    return data


filename1 = r"intersect on xoy.txt"
data = openreadtxt(filename1)
X = np.array(data)[:, 0]
Y = np.array(data)[:, 1]

# 定义符号和角度
x,y,z, R, delta0, vw = sy.symbols('x y z R delta0 vw')
rw = sy.Matrix([x, y, z])
k = R / sy.tan(delta0)
WtoF = sy.Matrix([[sy.cos(vw), -sy.sin(vw), 0], [sy.sin(vw), sy.cos(vw), 0], [0, 0, 1]])
Trans1 = sy.Matrix([0, 0, k * vw])
Rf_expr = WtoF.inv() * (rw -Trans1)


theta = sy.symbols('theta')

# 计算交点z坐标
f_plame=y*sy.tan(theta)
f_plame_fn=sy.lambdify((y),f_plame.subs({theta:pr["theta_value"]}))
Z=f_plame_fn(Y)



f_Rf=Rf_expr[2]
f_Rf_fn=sy.lambdify((R, delta0, vw,z), f_Rf)

vw_range = np.linspace(0, 2 * np.pi, 1000)  # vw的范围,将其分成1000个等间隔点
vw_coll=[]
for zi in Z:
    ffn = f_Rf_fn(pr["R"], pr["delta0"], vw_range,zi)
    pos=np.argmin(np.abs(ffn))
    vw_coll.append(vw_range[pos])

Rf_fn = sy.lambdify((R, delta0, vw,x,y,z), Rf_expr)

Rf_intersect = []

for xi,yi,zi,vi in zip(X, Y,Z,vw_coll):
    Rf = Rf_fn(pr["R"], pr["delta0"],vi,xi, yi, zi)
    Rf_intersect.append(Rf)

Rf_intersect = np.array(Rf_intersect).squeeze()


end = time.perf_counter()
execution_time = end - start
print(f"代码执行时间:{execution_time}秒")

# fig = plt.figure()
# ax = fig.add_subplot(111, projection='3d')
# # 绘制交线
# ax.plot(Rf_intersect[:,0], Rf_intersect[:,1], Rf_intersect[:,2],'r*')
# # 绘制螺旋面
# for Rf in Rf_values:
#     ax.plot(Rf[0,:], Rf[1,:], Rf[2,:])
# # 绘制平面
# ax.plot_surface(X_p, Y_p, Z_p)
# ax.set_xlabel('X')
# ax.set_ylabel('Y')
# ax.set_zlabel('Z')
#
# plt.show()
fig = plt.figure(figsize=(5, 5))
plt.rcParams['xtick.direction'] = 'in'  # 将x周的刻度线方向设置向内
plt.rcParams['ytick.direction'] = 'in'  # 将y轴的刻度方向设置向内
clist = ['blue', 'red', 'green', 'black', 'darkgreen', 'lime', 'gold', 'purple', 'green', 'cyan', 'salmon', 'grey',
             'mediumvioletred', 'darkkhaki', 'gray', 'darkcyan', 'violet', 'powderblue']
# ==========================================
# 参数方程画料棒圆形
theta_blank = np.arange(0, 2 * np.pi, 0.01)
x_blank = 0 + pr["R"] * np.cos(theta_blank)
y_blank = 0 + pr["R"] * np.sin(theta_blank)
plt.plot(x_blank, y_blank, c=clist[0])
#draw cut lip after pointing
plt.scatter(Y,X,label="intersect on xoy")
#draw helical contour and gringding
plt.scatter(Rf_intersect[:,1],Rf_intersect[:,0],label="curve data")
plt.legend()
plt.tight_layout()
plt.show()

7、总结

本案例实现了由离散数据点构成的曲线做螺旋运动后与已知平面相交的问题,包括两个方面,一是由已知点求交点,二是由交点反求已知点。

本案例可用于螺旋槽的加工计算。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值