如何在Silverlight中点击测试形状?

时间:2012-01-25 17:43:06

标签: c# .net silverlight geometry 2d

我需要能够确定给定点落入哪个形状。会有重叠的形状,我需要找到面积最小的Shape。例如,给定下图中所示的形状和点,以下内容将成立:

  • 第3点 - 与明星碰撞
  • 第2点 - 与钻石碰撞
  • 第1点 - 与圈子碰撞

enter image description here

鉴于此,我想知道是否有内置的方法来完成所需的工作。

2 个答案:

答案 0 :(得分:0)

如果要手动绘制这些形状,可以将第二个绘图传递到单独的缓冲区中,而不是绘制形状,如果像素在形状内,则将ID写入缓冲区。然后你的命中测试只需索引到该缓冲区并检索ID。您可以完全重复使用绘图代码,当您有更多的形状,顶点和点击进行测试时,它会更好地扩展。

答案 1 :(得分:0)

我已经找到了满足要求的解决方案,仍然有兴趣听听是否有更好的方法。我的方法如下:通过边界框进行命中测试,然后根据几何类型进行几何命中测试。

对于多边形,我已将http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes /pnpoly.html提到的C代码改编为C#。

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
  int i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
     (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
       c = !c;
  }
  return c;
}

对于Ellipses,我已经改编了这段代码:http://msdn.microsoft.com/en-us/library/aa231172%28v=vs.60%29.aspx

BOOL CCircCtrl::InCircle(CPoint& point)
{
    CRect rc;
    GetClientRect(rc);
    GetDrawRect(&rc);

    // Determine radii
    double a = (rc.right - rc.left) / 2;
    double b = (rc.bottom - rc.top) / 2;

    // Determine x, y
    double x = point.x - (rc.left + rc.right) / 2;
    double y = point.y - (rc.top + rc.bottom) / 2;

    // Apply ellipse formula
    return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}