-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_window_projection.rb
More file actions
157 lines (128 loc) · 5.75 KB
/
test_window_projection.rb
File metadata and controls
157 lines (128 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# 测试窗户投影逻辑修复 - 新版本
# 验证窗户能够正确定位到墙体中线上,并根据尺寸计算最终位置
require 'sketchup.rb'
# 模拟墙体数据
wall_data = {
"start" => [100.775, 33.3877, 0], # 墙体中线起点
"end" => [100.775, 68.7178, 0], # 墙体中线终点
"thickness" => 275.3047970963635 # 墙体厚度(毫米)
}
# 模拟窗户数据
window_data = {
"position" => [2697.325464907619, 1296.7396494091358], # 窗户位置
"size" => [800.0, 275.3047970963635], # 窗户尺寸
"height" => 1200.0 # 窗户高度
}
puts "=== 测试新的窗户定位逻辑 ==="
puts "墙体数据:"
puts " 中线起点: #{wall_data['start']}"
puts " 中线终点: #{wall_data['end']}"
puts " 厚度: #{wall_data['thickness']}mm"
puts "\n窗户数据:"
puts " 位置: #{window_data['position']}"
puts " 尺寸: #{window_data['size']}"
puts " 高度: #{window_data['height']}mm"
# 计算墙体方向
wall_start = Geom::Point3d.new(*wall_data["start"])
wall_end = Geom::Point3d.new(*wall_data["end"])
wall_vector = wall_end - wall_start
wall_direction = wall_vector.normalize
puts "\n墙体几何信息:"
puts " 墙体方向向量: #{wall_direction.inspect}"
puts " 墙体长度: #{wall_vector.length.round(6)}m"
# 计算墙体法线方向
wall_normal = wall_direction.cross(Geom::Vector3d.new(0, 0, 1)).normalize
puts " 墙体法线方向: #{wall_normal.inspect}"
# 墙体厚度
wall_thickness_m = wall_data["thickness"] * 0.001 # 转换为米
puts " 墙体厚度: #{wall_thickness_m.round(6)}m"
# 模拟窗户中心点(转换后的3D坐标)
# 正确计算:窗户中心点Z坐标 = 离地高度 + 窗户高度的一半
height_pos_m = window_data["height"] * 0.001 # 1200mm -> 1.2m
height_m = window_data["size"][1] * 0.001 # 275.3mm -> 0.2753m
center_z = height_pos_m + (height_m / 2.0) # 1.2 + 0.13765 = 1.33765m
window_center = Geom::Point3d.new(106.194, 51.0527, center_z)
puts "\n窗户原始中心点: #{window_center.inspect}"
puts "Z坐标计算: 离地高度(#{height_pos_m.round(6)}m) + 窗户高度/2(#{height_m/2.0.round(6)}m) = #{center_z.round(6)}m"
# 第一步:将窗户position移动到墙体中线上
puts "\n=== 第一步:移动到墙体中线 ==="
window_to_wall_start = window_center - wall_start
t = window_to_wall_start.dot(wall_direction) / wall_vector.length
t = [0.0, [t, 1.0].min].max
puts "投影参数 t: #{t.round(6)} (0=起点, 1=终点)"
projection_distance = t * wall_vector.length
projection_vector = wall_direction.clone
projection_vector.length = projection_distance
projected_center_midline = wall_start + projection_vector
puts "窗户中心点投影到墙体中线: #{projected_center_midline.inspect}"
# 第二步:计算窗户在墙体中线上应该偏移多少
puts "\n=== 第二步:计算最终位置 ==="
# 窗户尺寸(模拟从window_corners计算)
window_width = 31.496063 # 从之前的输出获取
window_height = 10.838772
half_window_width = window_width / 2.0
puts "窗户半宽: #{half_window_width.round(6)}m"
# 计算最终中心点
if t == 0.0
# 窗户在墙体起点附近,向右偏移
offset_vector = wall_direction.clone
offset_vector.length = half_window_width
final_center = projected_center_midline + offset_vector
puts "窗户在墙体起点附近,向右偏移到: #{final_center.inspect}"
elsif t == 1.0
# 窗户在墙体终点附近,向左偏移
offset_vector = wall_direction.clone
offset_vector.length = half_window_width
final_center = projected_center_midline - offset_vector
puts "窗户在墙体终点附近,向左偏移到: #{final_center.inspect}"
else
# 窗户在墙体中间,居中放置
final_center = projected_center_midline
puts "窗户在墙体中间,居中放置: #{final_center.inspect}"
end
# 第三步:计算最终窗户角点
puts "\n=== 第三步:计算最终角点 ==="
half_width = window_width / 2.0
half_thickness = wall_thickness_m / 2.0
half_height = window_height / 2.0
puts "计算参数:"
puts " 半宽: #{half_width.round(6)}m"
puts " 半厚: #{half_thickness.round(6)}m"
puts " 半高: #{half_height.round(6)}m"
# 创建方向向量
width_direction = wall_direction.clone
thickness_direction = wall_normal.clone
height_direction = Geom::Vector3d.new(0, 0, 1)
# 创建偏移向量
width_offset = width_direction.clone
width_offset.length = half_width
thickness_offset = thickness_direction.clone
thickness_offset.length = half_thickness
height_offset = height_direction.clone
height_offset.length = half_height
# 计算四个角点
bottom_left = final_center - width_offset - thickness_offset - height_offset
bottom_right = final_center + width_offset - thickness_offset - height_offset
top_right = final_center + width_offset + thickness_offset + height_offset
top_left = final_center - width_offset + thickness_offset + height_offset
puts "\n最终窗户角点:"
puts " 左下角: #{bottom_left.inspect}"
puts " 右下角: #{bottom_right.inspect}"
puts " 右上角: #{top_right.inspect}"
puts " 左上角: #{top_left.inspect}"
# 验证窗户是否正确打穿墙体
puts "\n=== 验证结果 ==="
# 检查窗户的厚度是否覆盖整个墙体厚度
window_thickness = (top_right - bottom_right).length
puts "窗户厚度: #{window_thickness.round(6)}m"
puts "墙体厚度: #{wall_thickness_m.round(6)}m"
puts "厚度覆盖: #{window_thickness >= wall_thickness_m ? '完全覆盖' : '部分覆盖'}"
# 检查窗户中心是否在墙体中线上
center_x = final_center.x
wall_center_x = wall_start.x
x_error = (center_x - wall_center_x).abs
puts "窗户中心X坐标: #{center_x.round(6)}m"
puts "墙体中线X坐标: #{wall_center_x.round(6)}m"
puts "X坐标误差: #{x_error.round(6)}m"
puts "中心对齐: #{x_error < 0.001 ? '正确' : '有误'}"
puts "\n=== 测试完成 ==="