1

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

这个应用程序绘制代表多重图的直线和曲线。

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

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

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

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

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

4

1 回答 1

0

如果您有复杂形状的线条,您可以执行以下操作:

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

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

希望这可以帮助!

(提示:您可以使用更宽的 Pen 渲染“内部”线条,使其更加敏感)。

于 2012-11-06T07:21:15.760 回答