如何检测多图的边缘上的点击?

时间:2012-11-06 05:40:36

标签: winapi graph gdi+ edge-detection

我编写了一个基于win32 api的GUI应用程序,它使用GDI +功能,如DrawCurve()和DrawLine()。

此应用程序绘制代表多图的线条和曲线。

边缘的数据结构只是一个五个int的结构。 (x1,y1,x2,y2和id)

如果两个顶点之间只有一条边,则使用DrawLine()绘制直线段。 如果有多个边,则使用DrawCurve()绘制曲线 - 这里,我围绕两个顶点的中点展开直线边缘,使它们成为曲线。使用法线方程计算与其分开的一些单位像素的点。如果添加更多边,则选择与中点分开两个单位像素的像素,然后选择3个单位像素,依此类推。

现在我有两个关于检测边缘点击的问题。

  1. 在寻找直线边缘时,为了尽量缩短搜索时间,我该怎么办? 检查点击的像素是否在线段上非常简单,但如果边缘数量较大,则比较所有边缘将是低效的。似乎可以在O(log n)中进行,其中n是边数 编辑:此时边缘(类Edge)存储在std :: map中,映射边缘id(int) 到Edge对象,我正在考虑声明另一个将像素映射到边缘id的容器 我正在考虑使用二叉搜索树,但关键是什么呢?或者我应该只使用2D像素阵列?

  2. 我可以获得DrawCurve()使用的点数组吗?如果这是不可能的,那么我应该重新计算基数样条,得到点数组,并检查用户点击的点是否与该数组中的任何点匹配。

1 个答案:

答案 0 :(得分:0)

如果您有复杂的形状线,您可以按照以下步骤操作:

  • 创建一个与图表大小相同的内部位图,并用黑色填充。
  • 渲染图形时,还要渲染到此位图,您想要点击的边缘,但是,使用不同的颜色渲染它们。将这些颜色值与相应的ID一起存储在表中。这里重要的是颜色不同(独特)。
  • 单击图形时,将X和Y坐标传输到内部位图并读取像素。如果是非黑色,请在表格中查找颜色值并获取相关ID。

这种方式根本不需要担心形状,也不需要使用自己的曲线算法等等。成本是额外的内存,这将是一个考虑,但除非它是一个巨大的图形(在这种情况下你可以缓冲绘图),它在大多数情况下不是一个问题。您可以在第二遍中渲染内部位图,以使主要图形显得更快(像往常一样)。

希望这有帮助!

(提示:你可以用更宽的笔渲染“内部”线,这样它会变得更敏感)。