在这个CAD模式你是怎么保证底图,轮廓、缺陷坐标对的上的
admin |
2026-05-20 23:08 |
阅读 41 次
在现在这个 CAD 模式里,底图、轮廓、缺陷能对上,核心不是我自己去算三套坐标,而是:
三者都交给同一个 DisplayEx 控件,用同一套 ROI 和同一套坐标转换。
具体是这样:
- CAD 底图
ImageUtil.DisplayEx持有一个 vectorLayer- 它内部用
Layers[0].ROI去调rasterizer.RasterizeLayer(...) - 所以当前看到的底图,本质上就是“这个 ROI 的 CAD 栅格化结果”
- step 轮廓
- 我传给
DisplayEx.DrawPolygon(...)的点,直接是 CAD 坐标PointD(x, y) DisplayEx内部会用它自己的MainToPictureCoord(...)把这些 CAD 点映射到当前视图像素- 这套映射用的正是同一个
Layers[0].ROI
- 缺陷箭头 / 黄圈
- 我传给
DrawArrow(...)/DrawCircle(...)的也是同样的 CAD 坐标 - 它们和 step 一样,都走
DisplayEx同一套ROI -> 屏幕变换
所以现在不是:
- 底图一套坐标
- 轮廓一套坐标
- 缺陷一套坐标
而是:
- 底图栅格化用
Layers[0].ROI - 轮廓绘制用
Layers[0].ROI - 缺陷绘制也用
Layers[0].ROI
这就是它们能对上的根本原因。
如果再压成一句更直白的话:
不是我“算对了三层”,而是我让三层都只认 DisplayEx 这一套坐标系统。
如果你愿意,我下一条可以直接指出当前代码里是哪几个方法分别负责:
- 底图
- 轮廓
- 缺陷
- 视图移动/缩放
位图模式和 CAD 模式不一样。
位图模式里不是靠
DisplayEx统一三层,而是靠:数据库给的
LayerBitmapMatrix + 我们外层的_panelMatrix` 两层变换叠加起来对齐。具体是这样:
PaintBitmapPanel()这里先:
canvas.SetMatrix(_panelMatrix)canvas.DrawBitmap(bmp, 0, 0)所以位图本身的缩放平移,是
_panelMatrix控的。PaintBitmapPanel()这里不是直接拿 CAD 点去画,而是先用:
_viewModel.PanelMatrix把 CAD 坐标变成“底图像素坐标”:
这个
mat就是数据库里的LayerBitmapMatrix。然后再套外层:
_panelMatrix.MapPoint(...)或者直接在canvas.SetMatrix(_panelMatrix)下面画所以 step 是: CAD -> LayerBitmapMatrix -> 位图像素 -> 当前视图矩阵
PaintBitmapPanel()里的CadToScreen(...)逻辑和 step 一样:
PanelMatrix把缺陷中心从 CAD 坐标变成底图像素_panelMatrix变成屏幕坐标所以缺陷是: CAD -> LayerBitmapMatrix -> 位图像素 -> 当前视图矩阵
PanelMatrix负责把 CAD 坐标对到底图原始像素_panelMatrix负责把底图像素缩放/平移到当前视图所以:
_panelMatrixPanelMatrix,再吃_panelMatrix一句话概括:
CAD 模式是三层都交给
DisplayEx一套 ROI。位图模式是三层都经过同一套
LayerBitmapMatrix + 视图矩阵。如果你愿意,我下一条我可以直接把位图模式在代码里的那几行公式单独摘出来,给你一个更短的“看公式就懂”的版本。
对应关系主要在这几个地方:
EnsureCadDisplay()这里把 CAD layer 放进:
_cadDisplay.Layers.Clear()_cadDisplay.Layers.Add(_cadDisplayLayer)之后真正的底图栅格化不是我们自己做的,而是
DisplayEx.UpdatePicture(true)内部完成的。UpdateCadDisplayAnnotations()这里用:
_cadDisplay.DrawPolygon(points, ...)传进去的
points是PanelSteps的 CAD 坐标。UpdateCadDisplayAnnotations()这里用:
_cadDisplay.DrawArrow(new PointD(defect.CenterXY.X, defect.CenterXY.Y), ...)传进去的也是缺陷中心的 CAD 坐标。
UpdateCadDisplayAnnotations()这里用:
_cadDisplay.DrawCircle(new PointD(highlighted.CenterXY.X, highlighted.CenterXY.Y), ...)也是 CAD 坐标。
DisplayEx自己: DisplayEx.cs关键入口是:
UpdatePicture(...)PanZoom(...)GoToPoint(...)MainToPictureCoord(...)PictureToMainCoord(...)DisplayEx.UpdatePicture()用Layers[0].ROI去 rasterizeDrawPolygon()最终也走MainToPictureCoord(...)DrawArrow()/DrawCircle()也走MainToPictureCoord(...)也就是: 同一个
Layers[0].ROI决定底图显示范围,也决定轮廓和缺陷怎么投到屏幕上。所以你如果要排查“为什么偏了”,优先看这几类东西:
_cadDisplayLayer.ROI_cadDisplayLayer.RectangleUpdateCadDisplayAnnotations()DisplayEx.MainToPictureCoord()