1、设计阵形
python
# %% 圆环阵
r_cir = 0.25 # 半径/m
angles = 2 * np.pi / N * np.arange(N)
ele_x = r_cir * np.cos(angles)
ele_y = r_cir * np.sin(angles)
Data3 = np.column_stack((ele_x, ele_y, np.full(N, z_distance)))
2、打开blender绘制阵形
python
# 打开Blender文件
bpy.ops.wm.open_mainfile(filepath=blend_file_path)
3、创建发射器
python
##创建发射器################################
# 示例:设置水平和垂直视角
horizontal_angle = 2*sm1 # 水平视角,单位为度
vertical_angle = 2*sm2 # 垂直视角,单位为度
# 计算焦距和传感器尺寸
focal_length, sensor_width, sensor_height = calculate_focal_length_and_sensor_size(horizontal_angle, vertical_angle)
# 1. 创建发射器(相机)
emitter_collection = create_collection("Emitter")
bpy.ops.object.camera_add(location=(0, 0, 0)) # 起点位于原点
emitter = bpy.context.object
emitter.name = "Emitter"
# 隐藏相机的边框和相机图标
emitter.hide_set(True) # 在视图中隐藏对象
emitter.hide_render = True # 在渲染中隐藏对象
emitter.hide_viewport = True # 在视口中隐藏对象
# 设置相机不参与渲染和碰撞检测
emitter.cycles.is_visible_camera = False
emitter.cycles.is_visible_diffuse = False
emitter.cycles.is_visible_glossy = False
emitter.cycles.is_visible_transmission = False
emitter.cycles.is_visible_volume_scatter = False
# 设置相机的焦距和传感器尺寸
emitter.data.lens = focal_length
emitter.data.sensor_width = sensor_width
emitter.data.sensor_height = sensor_height
print(f"焦距: {focal_length} mm")
print(f"传感器宽度: {sensor_width} mm")
print(f"传感器高度: {sensor_height} mm")
# 计算宽高比
aspect_ratio = sensor_width / sensor_height
# # 设置相机的宽高比
# bpy.context.scene.render.resolution_x = 1920 # 假设水平分辨率
# bpy.context.scene.render.resolution_y = int(1920 / aspect_ratio) # 根据宽高比计算垂直分辨率
# 计算在指定距离处的边框宽度和高度
distance = -r_scan
frame_width = distance * math.tan(horizontal_angle / 2)
frame_height = distance * math.tan(vertical_angle / 2)
# 计算四个角点的局部坐标
half_width = frame_width / 2
half_height = frame_height / 2
corners_local = [
(-half_width, -half_height, distance),
(half_width, -half_height, distance),
(half_width, half_height, distance),
(-half_width, half_height, distance)
]
# 将局部坐标转换为世界坐标
corners_world = []
for corner in corners_local:
world_corner = emitter.matrix_world @ Vector(corner)
corners_world.append(world_corner)
# 创建四条线连接相机起点和边框角点
camera_location = emitter.location
for i, corner in enumerate(corners_world):
line_name = f"Line_{i}"
create_line(camera_location, corner, line_name)
# 假设 corners_world 是存储角点的列表
num_corners = len(corners_world)
for i in range(num_corners):
start = corners_world[i]
end = corners_world[(i + 1) % num_corners]
line_name = f"Border_Line_{i}"
create_line(start, end, line_name)
4、创建接收器:
python
#######创建接收器#######################################
receiver_collection = create_collection("Receivers")
receiver_material = bpy.data.materials.new(name="Receiver_Blue")
receiver_material.diffuse_color = (1, 0, 0, 1)
num_receivers = N
receiver_z = 0 # 接收器平面高度
receivers = []
for i in range(num_receivers):
angle = 2 * math.pi * i / num_receivers
receiver_x = Data3[i, 0]
receiver_y = Data3[i, 1]
receiver_z = z_distance
# 创建接收器(位置抬高到Z=0.25)
bpy.ops.mesh.primitive_cube_add(size=0.01, location=(receiver_x, receiver_y, receiver_z))
receiver = bpy.context.object
receiver.name = f"Receiver_{i}"
receiver.data.materials.append(receiver_material)
# 添加自定义属性
receiver["is_receiver"] = True
receiver["angle_deg"] = math.degrees(angle)
receiver_collection.objects.link(receiver)
# 对齐相机到接收器平面
align_camera_to_plane(emitter, receiver_z=receiver_z)
# 验证参数
print(f"相机位置: {emitter.location}")
print(f"相机旋转: {np.degrees(emitter.rotation_euler)} 度")
print(f"镜头焦距: {emitter.data.lens:.2f} mm")
5、 保存blender:
python
bpy.ops.wm.save_mainfile(filepath=blend_file_path)
6、 函数返回发射器、接收器的位置