zhong (钟鹏群) 3 週間 前
コミット
c7049fdec0
2 ファイル変更224 行追加5 行削除
  1. 143 5
      src/xxx.py
  2. 81 0
      src/yyy.py

+ 143 - 5
src/xxx.py

@@ -2,6 +2,7 @@ import pygame
 from pygame.locals import *
 from OpenGL.GL import *
 from OpenGL.GLU import *
+import math
 
 def draw_wire_cube():
     """绘制线框立方体"""
@@ -75,9 +76,74 @@ def draw_solid_cube():
             glVertex3fv(vertices[vertex])
         glEnd()
 
-def draw_small_cube(position, size=0.4):
+# 字体初始化
+font = None
+
+def init_font():
+    global font
+    pygame.font.init()
+    font = pygame.font.SysFont('arial', 24)
+
+def draw_text_at_position(text, position):
+    """在3D空间中指定位置绘制文本"""
+    global font
+    if font is None:
+        init_font()
+    
+    # 创建文本表面
+    text_surface = font.render(text, True, (255, 255, 255))  # 白色文字
+    text_data = pygame.image.tostring(text_surface, "RGBA", True)
+    
+    # 保存当前矩阵状态
+    glPushMatrix()
+    
+    # 移动到目标位置
+    glTranslatef(position[0], position[1], position[2])
+    
+    # 获取模型视图矩阵,使文本面向摄像机
+    matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
+    
+    # 使文本始终面向摄像机(billboard效果)
+    glLoadIdentity()
+    # 恢复摄像机视角,但保持位置
+    glTranslatef(position[0], position[1], position[2])
+    
+    # 创建纹理
+    texture_id = glGenTextures(1)
+    glBindTexture(GL_TEXTURE_2D, texture_id)
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, text_surface.get_width(), 
+                 text_surface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, text_data)
+    
+    # 计算文本尺寸以适当缩放
+    width = text_surface.get_width()
+    height = text_surface.get_height()
+    scale_factor = 0.05  # 缩放因子
+    
+    # 绘制带纹理的四边形来显示文本
+    glEnable(GL_TEXTURE_2D)
+    glEnable(GL_BLEND)
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+    
+    glBegin(GL_QUADS)
+    glTexCoord2f(0, 0); glVertex3f(-width * scale_factor/2, -height * scale_factor/2, 0.01)  # 稍微高于小正方体表面
+    glTexCoord2f(1, 0); glVertex3f(width * scale_factor/2, -height * scale_factor/2, 0.01)
+    glTexCoord2f(1, 1); glVertex3f(width * scale_factor/2, height * scale_factor/2, 0.01)
+    glTexCoord2f(0, 1); glVertex3f(-width * scale_factor/2, height * scale_factor/2, 0.01)
+    glEnd()
+    
+    glDisable(GL_TEXTURE_2D)
+    
+    # 清理纹理
+    glDeleteTextures([texture_id])
+    
+    glPopMatrix()
+
+def draw_small_cube(position, cube_number, size=0.4):
     """绘制一个小正方体
     position: 小正方体的位置 (x, y, z)
+    cube_number: 小正方体的编号 (从1开始)
     size: 小正方体的大小 (默认为0.4,即大正方体的一半减去0.1单位)
     """
     x, y, z = position
@@ -112,10 +178,62 @@ def draw_small_cube(position, size=0.4):
     # 绘制每个面
     for surface in surfaces:
         glBegin(GL_QUADS)
-        glColor4f(1.0, 1.0, 0.0, 0.1)  # 黄色,20%透明度(更不透明,更显眼)
+        glColor4f(1.0, 1.0, 0.0, 0.3)  # 黄色,30%透明度
         for vertex in surface:
             glVertex3fv(vertices[vertex])
         glEnd()
+    
+    # 在小正方体上方绘制编号文本
+    draw_text_at_position(str(cube_number), (x, y, z + size/2 + 0.05))  # 在小正方体顶部稍高处显示编号
+
+def hsv_to_rgb(h, s, v):
+    """将HSV颜色值转换为RGB颜色值
+    h: 色相 (0-1)
+    s: 饱和度 (0-1)
+    v: 明度 (0-1)
+    返回: RGB元组 (r, g, b),每个值在0-1之间
+    """
+    if s == 0.0:
+        return v, v, v
+    
+    i = int(h * 6)
+    f = (h * 6) - i
+    p = v * (1 - s)
+    q = v * (1 - s * f)
+    t = v * (1 - s * (1 - f))
+    
+    i %= 6
+    if i == 0:
+        return v, t, p
+    if i == 1:
+        return q, v, p
+    if i == 2:
+        return p, v, t
+    if i == 3:
+        return p, q, v
+    if i == 4:
+        return t, p, v
+    if i == 5:
+        return v, p, q
+
+def draw_number_labels(screen, small_cube_positions):
+    """在屏幕角落绘制编号标签"""
+    pygame.font.init()
+    font = pygame.font.SysFont('arial', 16)
+    
+    # 绘制编号列表
+    for i, pos in enumerate(small_cube_positions):
+        num = i + 1
+        text = f"#{num}: ({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f})"
+        text_surface = font.render(text, True, (255, 255, 255))  # 白色文字
+        # 在屏幕左上角垂直排列显示
+        screen.blit(text_surface, (10, 10 + i * 20))
+        
+        # 如果标签太多,限制显示数量
+        if i >= 19:  # 只显示前20个,避免超出屏幕
+            text_surface = font.render("...", True, (255, 255, 255))
+            screen.blit(text_surface, (10, 10 + 20 * 20))
+            break
 
 def main():
     # 内部小正方体每条边的数量(完全立方数:inner_cube^3个小正方体)
@@ -123,7 +241,7 @@ def main():
     
     pygame.init()
     display = (800, 600)
-    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
+    screen = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
     pygame.display.set_caption("透明3D正方体与内部小正方体")
 
@@ -167,8 +285,9 @@ def main():
         # 小正方体边长 = spacing * 0.8 (留一些间隙)
         small_cube_size = min(spacing * 0.8, 0.8)  # 限制最大尺寸
         
-        for pos in small_cube_positions:
-            draw_small_cube(pos, size=small_cube_size)
+        # 绘制编号的小正方体
+        for i, pos in enumerate(small_cube_positions):
+            draw_small_cube(pos, i+1, size=small_cube_size)
 
         # 绘制外部大透明正方体
         draw_solid_cube()
@@ -177,6 +296,25 @@ def main():
         glColor3f(1.0, 1.0, 1.0)  # 白色线框
         draw_wire_cube()
 
+        # 切换到2D模式绘制编号标签
+        glDisable(GL_DEPTH_TEST)
+        glMatrixMode(GL_PROJECTION)
+        glPushMatrix()
+        glLoadIdentity()
+        glOrtho(0, 800, 600, 0, -1, 1)  # 设置2D正交投影
+        glMatrixMode(GL_MODELVIEW)
+        glPushMatrix()
+        glLoadIdentity()
+        
+        # 绘制编号标签
+        draw_number_labels(screen, small_cube_positions)
+        
+        # 恢复3D模式
+        glPopMatrix()
+        glMatrixMode(GL_PROJECTION)
+        glPopMatrix()
+        glEnable(GL_DEPTH_TEST)
+
         pygame.display.flip()
         clock.tick(60)
 

+ 81 - 0
src/yyy.py

@@ -0,0 +1,81 @@
+import tkinter as tk
+
+class SquareWindow:
+    def __init__(self):
+        # Create the main window
+        self.root = tk.Tk()
+        self.root.title("Square Window")
+        
+        # Set window size to 1000x1000 pixels
+        self.window_size = 1000
+        self.root.geometry(f"{self.window_size}x{self.window_size}")
+        
+        # Create a canvas to draw on
+        self.canvas = tk.Canvas(self.root, width=self.window_size, height=self.window_size, bg="white")
+        self.canvas.pack(fill=tk.BOTH, expand=True)
+        
+        # Draw a square that is 90% of the window size
+        square_size = int(self.window_size * 0.9)  # 90% of 1000 = 900
+        
+        # Calculate the position to center the square
+        margin = (self.window_size - square_size) // 2  # (1000 - 900) / 2 = 50
+        
+        # Coordinates for the square (centered in the window)
+        x1, y1 = margin, margin
+        x2, y2 = margin + square_size, margin + square_size
+        
+        # Draw the square
+        self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", width=2)
+        
+        # Determine how many squares to draw based on the desired number
+        desired_number = 79  # You can change this to any number you want to draw
+        
+        # Find the closest perfect square that is >= desired_number
+        import math
+        n = math.ceil(math.sqrt(desired_number))  # For 19, sqrt(19) ≈ 4.36, ceil(4.36) = 5, so n=5
+        actual_number = n * n  # For n=5, actual_number = 25
+        
+        print(f"You wanted {desired_number} squares, but we're drawing {actual_number} squares in a {n}x{n} grid.")
+        
+        # Calculate the size of each small square (1/n of the main square's side minus 5 pixels)
+        small_square_size = (square_size // n) - 5  # (900 / 5) - 5 = 175 pixels
+        
+        # Draw only the required number of squares (up to desired_number) in an n x n grid
+        square_number = 1  # Start numbering from 1
+        
+        # Calculate spacing to distribute squares evenly with gaps
+        total_used_space = n * small_square_size  # Total space occupied by squares
+        remaining_space = square_size - total_used_space  # Remaining space for gaps
+        gap_per_row = remaining_space // (n + 1)  # Gap between squares and margins
+        
+        for i in range(n):  # Rows
+            for j in range(n):  # Columns
+                if square_number > desired_number:
+                    break  # Stop drawing if we've reached the desired number
+                
+                # Calculate position for each small square with proper spacing
+                small_x = x1 + gap_per_row + j * (small_square_size + gap_per_row)
+                small_y = y1 + gap_per_row + i * (small_square_size + gap_per_row)
+                
+                # Draw the small square
+                self.canvas.create_rectangle(
+                    small_x, small_y, 
+                    small_x + small_square_size, small_y + small_square_size,
+                    outline="blue", width=1
+                )
+                
+                # Add number in the center of each small square
+                center_x = small_x + small_square_size // 2
+                center_y = small_y + small_square_size // 2
+                self.canvas.create_text(center_x, center_y, text=str(square_number), fill="red", font=("Arial", 10))
+                
+                square_number += 1
+            if square_number > desired_number:
+                break  # Break outer loop as well if we've reached the desired number
+        
+    def run(self):
+        self.root.mainloop()
+
+if __name__ == "__main__":
+    app = SquareWindow()
+    app.run()