160 lines
5.7 KiB
Python
160 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
def test_coordinate_conversion():
|
||
"""测试坐标转换"""
|
||
|
||
print("=== 坐标转换测试 ===\n")
|
||
|
||
# 假设窗口大小
|
||
window_width = 800
|
||
window_height = 600
|
||
|
||
print(f"窗口大小: {window_width} x {window_height}")
|
||
print("\n测试不同位置的坐标转换:")
|
||
|
||
test_points = [
|
||
# (屏幕坐标, 描述)
|
||
((0, 0), "左上角"),
|
||
((window_width/2, window_height/2), "中心点"),
|
||
((window_width, window_height), "右下角"),
|
||
((window_width/4, window_height/4), "左上象限"),
|
||
((3*window_width/4, 3*window_height/4), "右下象限"),
|
||
((419, 96), "用户点击的位置"), # 来自之前的日志
|
||
]
|
||
|
||
for (screen_x, screen_y), description in test_points:
|
||
# 方法1:标准转换(我们当前使用的)
|
||
normalized_x1 = (2.0 * screen_x / window_width) - 1.0
|
||
normalized_y1 = 1.0 - (2.0 * screen_y / window_height)
|
||
|
||
# 方法2:简单转换
|
||
normalized_x2 = (screen_x / window_width) * 2 - 1
|
||
normalized_y2 = 1 - (screen_y / window_height) * 2
|
||
|
||
# 方法3:不反转Y轴
|
||
normalized_x3 = (2.0 * screen_x / window_width) - 1.0
|
||
normalized_y3 = (2.0 * screen_y / window_height) - 1.0
|
||
|
||
print(f"\n{description}: 屏幕坐标({screen_x:.0f}, {screen_y:.0f})")
|
||
print(f" 方法1 (当前): ({normalized_x1:.3f}, {normalized_y1:.3f})")
|
||
print(f" 方法2 (等价): ({normalized_x2:.3f}, {normalized_y2:.3f})")
|
||
print(f" 方法3 (不反转Y): ({normalized_x3:.3f}, {normalized_y3:.3f})")
|
||
|
||
# 验证是否在有效范围内
|
||
in_range1 = -1 <= normalized_x1 <= 1 and -1 <= normalized_y1 <= 1
|
||
in_range3 = -1 <= normalized_x3 <= 1 and -1 <= normalized_y3 <= 1
|
||
|
||
print(f" 方法1 在范围内: {in_range1}")
|
||
print(f" 方法3 在范围内: {in_range3}")
|
||
|
||
def test_qt_coordinate_precision():
|
||
"""测试Qt坐标精度问题"""
|
||
print("\n=== Qt坐标精度测试 ===")
|
||
|
||
# 模拟真实的Qt widget大小(来自日志)
|
||
qt_width = 1238.0
|
||
qt_height = 725.0
|
||
|
||
# 模拟真实的点击位置(来自日志)
|
||
click_x = 615
|
||
click_y = 237
|
||
|
||
print(f"Qt Widget大小: {qt_width} x {qt_height}")
|
||
print(f"点击位置: ({click_x}, {click_y})")
|
||
|
||
# 当前的转换方法
|
||
normalized_x = (2.0 * click_x / qt_width) - 1.0
|
||
normalized_y = 1.0 - (2.0 * click_y / qt_height)
|
||
|
||
print(f"归一化坐标: ({normalized_x:.6f}, {normalized_y:.6f})")
|
||
|
||
# 验证屏幕中心
|
||
center_x = qt_width / 2
|
||
center_y = qt_height / 2
|
||
|
||
center_norm_x = (2.0 * center_x / qt_width) - 1.0
|
||
center_norm_y = 1.0 - (2.0 * center_y / qt_height)
|
||
|
||
print(f"屏幕中心: ({center_x}, {center_y}) -> ({center_norm_x:.6f}, {center_norm_y:.6f})")
|
||
|
||
# 分析点击位置相对于中心的偏移
|
||
offset_from_center_x = click_x - center_x
|
||
offset_from_center_y = click_y - center_y
|
||
|
||
print(f"相对于中心的偏移: ({offset_from_center_x:.1f}, {offset_from_center_y:.1f})")
|
||
|
||
# 计算归一化偏移
|
||
norm_offset_x = offset_from_center_x / (qt_width / 2)
|
||
norm_offset_y = -offset_from_center_y / (qt_height / 2) # Y轴反转
|
||
|
||
print(f"归一化偏移: ({norm_offset_x:.6f}, {norm_offset_y:.6f})")
|
||
|
||
# 预期的归一化坐标(从中心偏移)
|
||
expected_norm_x = norm_offset_x
|
||
expected_norm_y = norm_offset_y
|
||
|
||
print(f"预期归一化坐标: ({expected_norm_x:.6f}, {expected_norm_y:.6f})")
|
||
|
||
# 比较
|
||
diff_x = abs(normalized_x - expected_norm_x)
|
||
diff_y = abs(normalized_y - expected_norm_y)
|
||
|
||
print(f"坐标差异: X={diff_x:.6f}, Y={diff_y:.6f}")
|
||
|
||
def test_panda3d_coordinate_systems():
|
||
"""测试Panda3D的坐标系统"""
|
||
print("\n=== Panda3D坐标系统 ===")
|
||
print("屏幕坐标系统:")
|
||
print(" Qt: 左上角(0,0), 右下角(w,h), Y轴向下")
|
||
print(" Panda3D: 左下角(-1,-1), 右上角(1,1), Y轴向上")
|
||
print()
|
||
print("3D世界坐标系统:")
|
||
print(" X轴: 向右为正")
|
||
print(" Y轴: 向前为正(远离相机)")
|
||
print(" Z轴: 向上为正")
|
||
print()
|
||
print("相机坐标系统:")
|
||
print(" X轴: 向右为正")
|
||
print(" Y轴: 向前为正(相机朝向)")
|
||
print(" Z轴: 向上为正")
|
||
|
||
def test_coordinate_alignment_issue():
|
||
"""测试坐标对齐问题"""
|
||
print("\n=== 坐标对齐问题分析 ===")
|
||
|
||
qt_width = 1238.0
|
||
qt_height = 725.0
|
||
|
||
print("测试不同位置的归一化坐标:")
|
||
|
||
test_positions = [
|
||
("左边缘", 50, qt_height/2),
|
||
("右边缘", qt_width-50, qt_height/2),
|
||
("上边缘", qt_width/2, 50),
|
||
("下边缘", qt_width/2, qt_height-50),
|
||
("左上角", 100, 100),
|
||
("右下角", qt_width-100, qt_height-100),
|
||
("中心", qt_width/2, qt_height/2),
|
||
("用户点击", 615, 237)
|
||
]
|
||
|
||
for name, x, y in test_positions:
|
||
# 当前方法
|
||
norm_x = (2.0 * x / qt_width) - 1.0
|
||
norm_y = 1.0 - (2.0 * y / qt_height)
|
||
|
||
# 期望:点击边缘应该接近±1,点击中心应该接近0
|
||
# 左边缘应该接近-1,右边缘应该接近+1
|
||
# 上边缘应该接近+1,下边缘应该接近-1
|
||
|
||
expected_x = (x - qt_width/2) / (qt_width/2)
|
||
expected_y = (qt_height/2 - y) / (qt_height/2)
|
||
|
||
print(f"{name:8s}: 实际({norm_x:6.3f}, {norm_y:6.3f}) 期望({expected_x:6.3f}, {expected_y:6.3f})")
|
||
|
||
if __name__ == "__main__":
|
||
test_coordinate_conversion()
|
||
test_qt_coordinate_precision()
|
||
test_panda3d_coordinate_systems()
|
||
test_coordinate_alignment_issue() |