door_analysis.html 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <style>
  6. body { font-family: monospace; background: #1a1a2e; color: #e0e0e0; display: flex; flex-direction: column; align-items: center; padding: 30px; }
  7. h2 { color: #e94560; }
  8. .legend { margin-top: 20px; font-size: 13px; line-height: 2; }
  9. .legend span { display: inline-block; width: 14px; height: 14px; vertical-align: middle; margin-right: 6px; border-radius: 2px; }
  10. </style>
  11. </head>
  12. <body>
  13. <h2>Door 9 问题分析:bbox 高宽比异常导致门线过长</h2>
  14. <canvas id="c" width="700" height="700"></canvas>
  15. <div class="legend">
  16. <span style="background:#4a90d9"></span> 门 bbox (14×130px)<br>
  17. <span style="background:#e94560"></span> 墙线段 (垂直, x=672)<br>
  18. <span style="background:#50fa7b"></span> 当前生成的门线 (2.6m, 取交点间距=130px)<br>
  19. <span style="background:#f1fa8c"></span> 正确的门线 (应为 14px ≈ 0.14m)<br>
  20. <span style="background:#666"></span> 相邻墙线段
  21. </div>
  22. <script>
  23. const c = document.getElementById('c');
  24. const ctx = c.getContext('2d');
  25. const S = 2.5;
  26. const OX = 50, OY = 50;
  27. function px(x, y) { return [OX + x * S, OY + y * S]; }
  28. // Draw all wall segments
  29. const segments = [
  30. [[420,266],[420,360]], [[420,360],[537,360]], [[537,360],[537,266]], [[537,266],[420,266]],
  31. [[458,424],[509,424]], [[509,424],[698,424]], [[698,424],[698,379]], [[698,379],[740,379]],
  32. [[740,379],[740,266]], [[740,266],[560,266]], [[560,266],[560,304]], [[560,304],[537,304]],
  33. [[537,304],[537,360]], [[537,360],[458,360]], [[458,360],[458,424]],
  34. [[336,326],[336,360]], [[336,360],[399,360]], [[399,360],[399,326]], [[399,326],[336,326]],
  35. [[458,360],[336,360]], [[336,360],[336,514]], [[336,514],[458,514]], [[458,514],[458,360]],
  36. [[336,404],[230,404]], [[230,404],[230,426]], [[230,426],[230,559]], [[230,559],[336,559]], [[336,559],[336,404]],
  37. [[521,575],[698,575]], [[698,575],[698,480]], [[698,480],[742,480]], [[698,480],[698,424]], [[698,424],[521,424]], [[521,424],[521,575]],
  38. [[458,424],[458,575]], [[458,575],[521,575]], [[521,575],[521,424]], [[521,424],[458,424]],
  39. [[336,514],[336,575]], [[336,575],[379,575]], [[379,575],[458,575]], [[458,575],[458,514]], [[458,514],[336,514]],
  40. [[230,559],[230,647]], [[230,647],[263,647]], [[263,647],[263,669]], [[263,669],[336,669]], [[336,669],[336,606]], [[336,606],[336,559]], [[336,559],[230,559]],
  41. [[336,675],[336,742]], [[336,742],[672,742]], [[672,742],[672,575]], [[672,575],[458,575]], [[458,575],[458,606]], [[458,606],[336,606]], [[336,606],[336,675]],
  42. [[788,575],[672,575]], [[672,575],[672,742]], [[672,742],[716,742]], [[716,742],[716,704]], [[716,704],[788,704]], [[788,704],[788,575]],
  43. [[672,575],[672,742]], // seg 26: the wall Door 9 intersects
  44. ];
  45. // Draw non-target segments
  46. segments.forEach(s => {
  47. const [x1,y1] = px(s[0][0], s[0][1]);
  48. const [x2,y2] = px(s[1][0], s[1][1]);
  49. ctx.beginPath();
  50. ctx.moveTo(x1, y1);
  51. ctx.lineTo(x2, y2);
  52. ctx.strokeStyle = '#555';
  53. ctx.lineWidth = 2;
  54. ctx.stroke();
  55. });
  56. // Draw target segment (seg 26)
  57. const [x1,y1] = px(672, 575);
  58. const [x2,y2] = px(672, 742);
  59. ctx.beginPath();
  60. ctx.moveTo(x1, y1);
  61. ctx.lineTo(x2, y2);
  62. ctx.strokeStyle = '#e94560';
  63. ctx.lineWidth = 3;
  64. ctx.stroke();
  65. // Draw door bbox (14x130 at 666,596)
  66. const bx = 666, by = 596, bw = 14, bh = 130;
  67. const [bx1,by1] = px(bx, by);
  68. const [bx2,by2] = px(bx+bw, by+bh);
  69. ctx.fillStyle = 'rgba(74,144,217,0.3)';
  70. ctx.fillRect(bx1, by1, bx2-bx1, by2-by1);
  71. ctx.strokeStyle = '#4a90d9';
  72. ctx.lineWidth = 2;
  73. ctx.strokeRect(bx1, by1, bx2-bx1, by2-by1);
  74. // Draw intersection points (wall x=672 crosses bbox at y=596 and y=726)
  75. const wallX = 672;
  76. const ip1 = px(wallX, by); // top edge intersection
  77. const ip2 = px(wallX, by+bh); // bottom edge intersection
  78. ctx.beginPath();
  79. ctx.arc(ip1[0], ip1[1], 5, 0, Math.PI*2);
  80. ctx.fillStyle = '#50fa7b';
  81. ctx.fill();
  82. ctx.beginPath();
  83. ctx.arc(ip2[0], ip2[1], 5, 0, Math.PI*2);
  84. ctx.fillStyle = '#50fa7b';
  85. ctx.fill();
  86. // Current door line (wrong - full height)
  87. ctx.beginPath();
  88. ctx.moveTo(ip1[0], ip1[1]);
  89. ctx.lineTo(ip2[0], ip2[1]);
  90. ctx.strokeStyle = '#50fa7b';
  91. ctx.lineWidth = 4;
  92. ctx.stroke();
  93. // Correct door line (14px tall, vertical, centered on wall)
  94. const cx = bx + bw/2;
  95. const cy = by + bh/2;
  96. const correctHalf = 7; // 14/2
  97. const cp1 = px(wallX, cy - correctHalf);
  98. const cp2 = px(wallX, cy + correctHalf);
  99. ctx.beginPath();
  100. ctx.moveTo(cp1[0], cp1[1]);
  101. ctx.lineTo(cp2[0], cp2[1]);
  102. ctx.strokeStyle = '#f1fa8c';
  103. ctx.lineWidth = 4;
  104. ctx.setLineDash([4, 4]);
  105. ctx.stroke();
  106. ctx.setLineDash([]);
  107. // Labels
  108. ctx.font = '14px monospace';
  109. ctx.fillStyle = '#e0e0e0';
  110. ctx.fillText(`门 bbox: ${bw}×${bh}px`, bx1 - 100, by1 - 10);
  111. ctx.fillText(`墙穿过 bbox,交点间距 = ${bh}px`, bx1 + 30, by1 + bh*S/2 - 10);
  112. ctx.fillStyle = '#50fa7b';
  113. ctx.fillText(`← 当前: 取交点间距 = ${bh}px = ${(bh*0.02).toFixed(1)}m (错误!)`, ip2[0] + 15, ip2[1]);
  114. ctx.fillStyle = '#f1fa8c';
  115. ctx.fillText(`← 正确: bbox 短边 = ${bw}px = ${(bw*0.02).toFixed(1)}m`, cp1[0] - 180, cp1[1] + 25);
  116. ctx.fillStyle = '#e94560';
  117. ctx.fillText(`墙线段 seg26 (x=672, y=575→742)`, x2 + 10, (y1+y2)/2);
  118. ctx.fillStyle = '#4a90d9';
  119. ctx.fillText(`墙方向: 垂直 (dx≈0)`, bx1 - 150, by1 + bh*S/2);
  120. ctx.fillText(`→ 门宽 = bbox 较短边 = ${Math.min(bw,bh)}px`, bx1 - 150, by1 + bh*S/2 + 18);
  121. // Add dimension arrows on the bbox
  122. ctx.strokeStyle = '#f1fa8c';
  123. ctx.lineWidth = 1;
  124. // Short side arrow (left side of bbox)
  125. const arrowX = bx1 - 20;
  126. ctx.beginPath();
  127. ctx.moveTo(arrowX, by1);
  128. ctx.lineTo(arrowX, by2);
  129. ctx.stroke();
  130. ctx.fillStyle = '#f1fa8c';
  131. ctx.fillText(`${bw}px`, arrowX - 20, by1 + bh*S/2 + 5);
  132. // Long side arrow (bottom of bbox)
  133. const arrowY = by2 + 15;
  134. ctx.beginPath();
  135. ctx.moveTo(bx1, arrowY);
  136. ctx.lineTo(bx2, arrowY);
  137. ctx.stroke();
  138. ctx.fillStyle = '#50fa7b';
  139. ctx.fillText(`${bh}px`, bx1 + (bx2-bx1)/2 - 15, arrowY + 15);
  140. </script>
  141. </body>
  142. </html>