使用ImDrawList和AddRectFilled在ImGui绘制网格遇问题,求排查
网格绘制异常的坐标排查方案
1. 确认坐标原点映射逻辑
ImGui窗口绘图坐标原点在左上角,而坯料坐标通常以左下角为原点(CNC场景常见),直接映射会导致网格上下颠倒,需做坐标转换:
// 获取窗口可绘图区域高度(扣除标题栏等占用空间) float drawAreaHeight = ImGui::GetWindowHeight() - ImGui::GetFrameHeightWithSpacing(); // 将坯料Y坐标转换为窗口绘图坐标 float windowY = drawAreaHeight - (billetY * squareSize);
2. 修正squareSize计算逻辑
你当前按600/150得到4,但忽略了Y方向的比例(600/100=6),必须取最小比例保证坯料完整显示,否则会超出窗口范围:
ImVec2 billetSize = m_GCodeBuilder.GetBilletSize(); ImVec2 drawAreaSize = ImGui::GetContentRegionAvail(); // 计算XY方向缩放比例 float scaleX = drawAreaSize.x / billetSize.x; float scaleY = drawAreaSize.y / billetSize.y; // 取较小值作为squareSize,避免网格超出窗口 float squareSize = std::min(scaleX, scaleY);
按此计算,你的场景squareSize应为4,同时Y方向会剩余200像素,可添加居中逻辑让网格显示在窗口中间。
3. 检查网格绘制的循环边界
绘制网格线时,要确保坐标落在窗口可绘图区域内,示例代码如下:
ImVec2 drawAreaMin = ImGui::GetWindowContentRegionMin(); drawAreaMin.x += ImGui::GetWindowPos().x; drawAreaMin.y += ImGui::GetWindowPos().y; // 绘制垂直线 for (int x = 0; x <= billetSize.x; ++x) { float posX = drawAreaMin.x + x * squareSize; ImGui::GetWindowDrawList()->AddLine( ImVec2(posX, drawAreaMin.y), ImVec2(posX, drawAreaMin.y + billetSize.y * squareSize), IM_COL32(100, 100, 100, 255) ); } // 绘制水平线(转换Y坐标原点) float drawAreaMaxY = drawAreaMin.y + billetSize.y * squareSize; for (int y = 0; y <= billetSize.y; ++y) { float posY = drawAreaMaxY - y * squareSize; ImGui::GetWindowDrawList()->AddLine( ImVec2(drawAreaMin.x, posY), ImVec2(drawAreaMin.x + billetSize.x * squareSize, posY), IM_COL32(100, 100, 100, 255) ); }
4. 确认可绘图区域的获取方式
必须使用ImGui::GetContentRegionAvail()获取窗口内实际可绘图区域,不要直接用窗口整体尺寸600×600——窗口标题、边框等会占用空间,直接用整体尺寸会导致网格被截断。
5. 调试坐标的实用技巧
可以在代码中添加调试输出,或者绘制标记点验证坐标正确性:
// 打印关键坐标 printf("垂直线X坐标: %.2f, 水平线Y坐标: %.2f\n", posX, posY); // 绘制坯料四个角标记 ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(drawAreaMin.x, drawAreaMin.y), 3, IM_COL32(255, 0, 0, 255)); ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(drawAreaMin.x + billetSize.x * squareSize, drawAreaMaxY), 3, IM_COL32(0, 255, 0, 255));
内容的提问来源于stack exchange,提问作者NaniNoni
相关产品推荐
相关产品推荐

