在这个CAD模式你是怎么保证底图,轮廓、缺陷坐标对的上的

admin | 2026-05-20 23:08 | 阅读 41 次

在现在这个 CAD 模式里,底图、轮廓、缺陷能对上,核心不是我自己去算三套坐标,而是:

三者都交给同一个 DisplayEx 控件,用同一套 ROI 和同一套坐标转换。

具体是这样:

  1. CAD 底图
  • ImageUtil.DisplayEx 持有一个 vector Layer
  • 它内部用 Layers[0].ROI 去调 rasterizer.RasterizeLayer(...)
  • 所以当前看到的底图,本质上就是“这个 ROI 的 CAD 栅格化结果”
  1. step 轮廓
  • 我传给 DisplayEx.DrawPolygon(...) 的点,直接是 CAD 坐标 PointD(x, y)
  • DisplayEx 内部会用它自己的 MainToPictureCoord(...) 把这些 CAD 点映射到当前视图像素
  • 这套映射用的正是同一个 Layers[0].ROI
  1. 缺陷箭头 / 黄圈
  • 我传给 DrawArrow(...) / DrawCircle(...) 的也是同样的 CAD 坐标
  • 它们和 step 一样,都走 DisplayEx 同一套 ROI -> 屏幕 变换

所以现在不是:

  • 底图一套坐标
  • 轮廓一套坐标
  • 缺陷一套坐标

而是:

  • 底图栅格化用 Layers[0].ROI
  • 轮廓绘制用 Layers[0].ROI
  • 缺陷绘制也用 Layers[0].ROI

这就是它们能对上的根本原因。

如果再压成一句更直白的话:

不是我“算对了三层”,而是我让三层都只认 DisplayEx 这一套坐标系统。

如果你愿意,我下一条可以直接指出当前代码里是哪几个方法分别负责:

  • 底图
  • 轮廓
  • 缺陷
  • 视图移动/缩放

评论 (2)

发表评论
支持 Markdown 格式
a
admin 2026-05-20 23:09

位图模式和 CAD 模式不一样。

位图模式里不是靠 DisplayEx 统一三层,而是靠:

数据库给的 LayerBitmapMatrix + 我们外层的 _panelMatrix` 两层变换叠加起来对齐。

具体是这样:

  1. 底图 BoardImageViewView.xaml.cs 里的 PaintBitmapPanel()

这里先:

  • canvas.SetMatrix(_panelMatrix)
  • canvas.DrawBitmap(bmp, 0, 0)

所以位图本身的缩放平移,是 _panelMatrix 控的。

  1. step 轮廓 还是 PaintBitmapPanel()

这里不是直接拿 CAD 点去画,而是先用:

  • _viewModel.PanelMatrix

把 CAD 坐标变成“底图像素坐标”:

px = mat.ScaleX * x + mat.SkewX * y + mat.TransX;
py = bmpH - (mat.SkewY * x + mat.ScaleY * y + mat.TransY);

这个 mat 就是数据库里的 LayerBitmapMatrix

然后再套外层:

  • _panelMatrix.MapPoint(...) 或者直接在 canvas.SetMatrix(_panelMatrix) 下面画

所以 step 是: CAD -> LayerBitmapMatrix -> 位图像素 -> 当前视图矩阵

  1. 缺陷箭头 / 黄圈 也是 PaintBitmapPanel() 里的 CadToScreen(...)

逻辑和 step 一样:

  • 先用 PanelMatrix 把缺陷中心从 CAD 坐标变成底图像素
  • 再用 _panelMatrix 变成屏幕坐标

所以缺陷是: CAD -> LayerBitmapMatrix -> 位图像素 -> 当前视图矩阵

  1. 为什么能对上 因为位图模式下三者其实共享两套变换:
  • 第一层:PanelMatrix 负责把 CAD 坐标对到底图原始像素
  • 第二层:_panelMatrix 负责把底图像素缩放/平移到当前视图

所以:

  • 底图直接吃 _panelMatrix
  • 轮廓和缺陷先吃 PanelMatrix,再吃 _panelMatrix

一句话概括:

CAD 模式是三层都交给 DisplayEx 一套 ROI。
位图模式是三层都经过同一套 LayerBitmapMatrix + 视图矩阵

如果你愿意,我下一条我可以直接把位图模式在代码里的那几行公式单独摘出来,给你一个更短的“看公式就懂”的版本。

a
admin 2026-05-20 23:09

对应关系主要在这几个地方:

  1. 底图 BoardImageViewView.xaml.cs 里的 EnsureCadDisplay()

这里把 CAD layer 放进:

  • _cadDisplay.Layers.Clear()
  • _cadDisplay.Layers.Add(_cadDisplayLayer)

之后真正的底图栅格化不是我们自己做的,而是 DisplayEx.UpdatePicture(true) 内部完成的。

  1. 轮廓 还是在 BoardImageViewView.xaml.cs 里的 UpdateCadDisplayAnnotations()

这里用:

  • _cadDisplay.DrawPolygon(points, ...)

传进去的 pointsPanelSteps 的 CAD 坐标。

  1. 缺陷箭头 同一个 UpdateCadDisplayAnnotations()

这里用:

  • _cadDisplay.DrawArrow(new PointD(defect.CenterXY.X, defect.CenterXY.Y), ...)

传进去的也是缺陷中心的 CAD 坐标。

  1. 黄圈高亮 还是 UpdateCadDisplayAnnotations()

这里用:

  • _cadDisplay.DrawCircle(new PointD(highlighted.CenterXY.X, highlighted.CenterXY.Y), ...)

也是 CAD 坐标。

  1. 视图移动 / 缩放 真正执行的是 DisplayEx 自己: DisplayEx.cs

关键入口是:

  • UpdatePicture(...)
  • PanZoom(...)
  • GoToPoint(...)
  • MainToPictureCoord(...)
  • PictureToMainCoord(...)
  1. 为什么它们对得上 因为:
  • 底图:DisplayEx.UpdatePicture()Layers[0].ROI 去 rasterize
  • 轮廓:DrawPolygon() 最终也走 MainToPictureCoord(...)
  • 缺陷:DrawArrow() / DrawCircle() 也走 MainToPictureCoord(...)

也就是: 同一个 Layers[0].ROI 决定底图显示范围,也决定轮廓和缺陷怎么投到屏幕上。

所以你如果要排查“为什么偏了”,优先看这几类东西:

  • _cadDisplayLayer.ROI
  • _cadDisplayLayer.Rectangle
  • UpdateCadDisplayAnnotations()
  • DisplayEx.MainToPictureCoord()