|
|
@@ -1,5 +1,7 @@
|
|
|
+import time
|
|
|
import pygame
|
|
|
import math
|
|
|
+import os
|
|
|
from pygame.locals import *
|
|
|
from OpenGL.GL import *
|
|
|
from OpenGL.GLU import *
|
|
|
@@ -12,6 +14,9 @@ width, height = 800, 600
|
|
|
display = pygame.display.set_mode((width, height), DOUBLEBUF | OPENGL)
|
|
|
pygame.display.set_caption('3D Sphere')
|
|
|
|
|
|
+# 初始化剪贴板系统
|
|
|
+pygame.scrap.init()
|
|
|
+
|
|
|
# 启用深度测试
|
|
|
glEnable(GL_DEPTH_TEST)
|
|
|
|
|
|
@@ -25,10 +30,12 @@ glLightfv(GL_LIGHT0, GL_POSITION, light_position)
|
|
|
|
|
|
# 设置材质属性
|
|
|
material_ambient = [0.3, 0.7, 0.3, 1.0]
|
|
|
+material_diffuse = [0.0, 1.0, 0.0, 1.0]
|
|
|
material_specular = [0.3, 0.7, 0.3, 1.0]
|
|
|
material_shininess = [50.0]
|
|
|
|
|
|
glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient)
|
|
|
+glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse)
|
|
|
glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular)
|
|
|
glMaterialfv(GL_FRONT, GL_SHININESS, material_shininess)
|
|
|
|
|
|
@@ -37,14 +44,69 @@ gluPerspective(45, (width/height), 0.1, 50.0)
|
|
|
# 移动相机
|
|
|
glTranslatef(0.0, 0.0, -5)
|
|
|
|
|
|
-# 初始化3个绿球的角度
|
|
|
-ball_angles = [0, 120, 240] # 三个绿球的初始角度
|
|
|
-ball_radius = 0.5 # 绿球的半径
|
|
|
-distance = 2.5 # 绿球到黄球的距离
|
|
|
+# 文件夹结构
|
|
|
+folder_structure = []
|
|
|
+show_structure = False
|
|
|
+
|
|
|
+# 检查剪贴板内容
|
|
|
+def check_clipboard():
|
|
|
+ clipboard = pygame.scrap.get('text/plain')
|
|
|
+ if clipboard:
|
|
|
+ path = clipboard.decode('utf-8').strip()
|
|
|
+ if os.path.exists(path) and os.path.isdir(path):
|
|
|
+ return path
|
|
|
+ return None
|
|
|
+
|
|
|
+# 扫描文件夹函数(递归)
|
|
|
+def scan_folder(path, parent_distance=2, parent_angle=0, depth=0, max_depth=3):
|
|
|
+ structure = []
|
|
|
+ if depth >= max_depth:
|
|
|
+ return structure
|
|
|
+
|
|
|
+ if os.path.exists(path) and os.path.isdir(path):
|
|
|
+ items = os.listdir(path)
|
|
|
+ for i, item in enumerate(items):
|
|
|
+ item_path = os.path.join(path, item)
|
|
|
+ is_dir = os.path.isdir(item_path)
|
|
|
+ # 计算位置
|
|
|
+ angle = parent_angle + (i / len(items)) * 360
|
|
|
+ distance = parent_distance + 1
|
|
|
+ radius = 0.2 if is_dir else 0.1
|
|
|
+
|
|
|
+ # 添加当前项目
|
|
|
+ structure.append({
|
|
|
+ 'name': item,
|
|
|
+ 'path': item_path,
|
|
|
+ 'is_dir': is_dir,
|
|
|
+ 'angle': angle,
|
|
|
+ 'distance': distance,
|
|
|
+ 'radius': radius,
|
|
|
+ 'parent_distance': parent_distance,
|
|
|
+ 'parent_angle': parent_angle
|
|
|
+ })
|
|
|
+
|
|
|
+ # 递归扫描子文件夹
|
|
|
+ if is_dir:
|
|
|
+ structure.extend(scan_folder(item_path, distance, angle, depth + 1, max_depth))
|
|
|
+ return structure
|
|
|
+
|
|
|
+# 使用默认路径 E:\myaliyun\IamHere
|
|
|
+default_path = "E:\\myaliyun\\IamHere"
|
|
|
+if os.path.exists(default_path) and os.path.isdir(default_path):
|
|
|
+ folder_structure = scan_folder(default_path)
|
|
|
+ show_structure = True
|
|
|
+else:
|
|
|
+ # 启动时检查剪贴板
|
|
|
+ clipboard_path = check_clipboard()
|
|
|
+ if clipboard_path:
|
|
|
+ folder_structure = scan_folder(clipboard_path)
|
|
|
+ show_structure = True
|
|
|
|
|
|
# 主循环
|
|
|
running = True
|
|
|
while running:
|
|
|
+ # time.sleep(100)
|
|
|
+
|
|
|
# 处理事件
|
|
|
for event in pygame.event.get():
|
|
|
if event.type == pygame.QUIT:
|
|
|
@@ -53,45 +115,60 @@ while running:
|
|
|
# 清除屏幕
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
|
|
|
|
|
- # 旋转整个场景
|
|
|
+ # 旋转大球
|
|
|
glRotatef(1, 3, 1, 1)
|
|
|
|
|
|
- # 绘制黄球(中心球)
|
|
|
- glMaterialfv(GL_FRONT, GL_DIFFUSE, [1.0, 1.0, 0.0, 1.0]) # 黄色
|
|
|
+ # 绘制大球
|
|
|
quad = gluNewQuadric()
|
|
|
gluQuadricNormals(quad, GLU_SMOOTH)
|
|
|
gluSphere(quad, 1, 32, 32)
|
|
|
gluDeleteQuadric(quad)
|
|
|
|
|
|
- # 绘制3个绿球和连线
|
|
|
- glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.0, 1.0, 0.0, 1.0]) # 绿色
|
|
|
- for i, angle in enumerate(ball_angles):
|
|
|
- # 计算绿球位置
|
|
|
- angle_rad = math.radians(angle)
|
|
|
- x = distance * math.cos(angle_rad)
|
|
|
- y = distance * math.sin(angle_rad)
|
|
|
- z = 0
|
|
|
-
|
|
|
- # 绘制连线(连接到中心黄球)
|
|
|
- glBegin(GL_LINES)
|
|
|
- glVertex3f(0, 0, 0) # 中心黄球位置
|
|
|
- glVertex3f(x, y, z) # 绿球位置
|
|
|
- glEnd()
|
|
|
-
|
|
|
- # 保存当前矩阵
|
|
|
- glPushMatrix()
|
|
|
- # 移动到绿球位置
|
|
|
- glTranslatef(x, y, z)
|
|
|
- # 绘制绿球
|
|
|
- quad = gluNewQuadric()
|
|
|
- gluQuadricNormals(quad, GLU_SMOOTH)
|
|
|
- gluSphere(quad, ball_radius, 16, 16)
|
|
|
- gluDeleteQuadric(quad)
|
|
|
- # 恢复矩阵
|
|
|
- glPopMatrix()
|
|
|
-
|
|
|
- # 更新绿球角度
|
|
|
- ball_angles[i] = (angle + 1) % 360
|
|
|
+
|
|
|
+ print(folder_structure)
|
|
|
+
|
|
|
+ # 绘制文件夹结构
|
|
|
+ if show_structure:
|
|
|
+ for item in folder_structure:
|
|
|
+ # 计算当前项目位置
|
|
|
+ angle_rad = math.radians(item['angle'])
|
|
|
+ x = item['distance'] * math.cos(angle_rad)
|
|
|
+ y = item['distance'] * math.sin(angle_rad)
|
|
|
+ z = 0
|
|
|
+
|
|
|
+ # 计算父项目位置
|
|
|
+ parent_angle_rad = math.radians(item['parent_angle'])
|
|
|
+ parent_x = item['parent_distance'] * math.cos(parent_angle_rad)
|
|
|
+ parent_y = item['parent_distance'] * math.sin(parent_angle_rad)
|
|
|
+ parent_z = 0
|
|
|
+
|
|
|
+ # 绘制连线(连接到父项目)
|
|
|
+ glBegin(GL_LINES)
|
|
|
+ glVertex3f(parent_x, parent_y, parent_z) # 父项目位置
|
|
|
+ glVertex3f(x, y, z) # 当前项目位置
|
|
|
+ glEnd()
|
|
|
+
|
|
|
+ # 保存当前矩阵
|
|
|
+ glPushMatrix()
|
|
|
+ # 移动到当前项目位置
|
|
|
+ glTranslatef(x, y, z)
|
|
|
+ # 设置材质颜色(文件夹为绿色,文件为蓝色)
|
|
|
+ if item['is_dir']:
|
|
|
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.0, 1.0, 0.0, 1.0])
|
|
|
+ else:
|
|
|
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.0, 0.0, 1.0, 1.0])
|
|
|
+ # 绘制小球
|
|
|
+ quad = gluNewQuadric()
|
|
|
+ gluQuadricNormals(quad, GLU_SMOOTH)
|
|
|
+ gluSphere(quad, item['radius'], 16, 16)
|
|
|
+ gluDeleteQuadric(quad)
|
|
|
+ # 恢复材质颜色
|
|
|
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse)
|
|
|
+ # 恢复矩阵
|
|
|
+ glPopMatrix()
|
|
|
+
|
|
|
+ # 更新角度
|
|
|
+ item['angle'] = (item['angle'] + 1) % 360
|
|
|
|
|
|
# 交换缓冲区
|
|
|
pygame.display.flip()
|