C#中的GraphicsPath多边形拟合

时间:2010-11-26 21:04:25

标签: c# polygon graphicspath

我需要将任意形状的GraphicsPath“拟合”到定义的空间中(几乎总是一个矩形或圆形)。

我目前使用Matrix对象缩放GraphicsPath并且缩放工作正常,但问题是获得缩放因子。

我能想到的最好的技术是将GraphicsPath转换为Region,将Rectangle或Circle转换为Region,然后执行:

rgnShape.Intersect(rgnCircle);

然后检查是否:

rgnShape.IsEmpty()

然而,这只是告诉我,如果形状太大而不适合,则需要缩小形状,然后再试一次(可能很多次)。

是否有一种简单的方法可以立即计算缩放因子以适合多边形GraphicsPath,使其完全适合圆形。结果应该是仍然完全适合圆圈的最大多边形。

5 个答案:

答案 0 :(得分:2)

我不明白你为什么需要二元搜索。

获得形状的边界矩形后,如果您想要符合形状的目标矩形,则可以比较两个比率targetHeight / shapeHeighttargetWidth / shapeWidth

取较小的比例,并将其用作比例因子来缩放你的形状。

如果目标是圆形而不是矩形,则可以使用targetCircleDiameter / boundingRectangleDiagonal的比率来使用类似的解决方案,并将其用作比例因子。

答案 1 :(得分:2)

请参阅http://en.wikipedia.org/wiki/Smallest_circle_problem,了解有关此问题的讨论,而不是路径,而不是路径。

  1. 所以,这样做,使用rgnShape.Intersect(rgnCircle);检查它是否有效。如果失败,则取每条曲线并抓住距离您找到的圆心最远的点(对于任何给定的区域,可能有多个这样的点)。

  2. 将它们添加到您的积分列表中,重新应用算法。你不需要从头开始;您不需要考虑不在边界上的点(即,忽略原始调用算法找不到的“Set Q”中的点)。

  3. 请注意,这不再是线性的,因为生成递归调用的概率不再是第i个点的1 / i。

    这有一个必须明确处理的边缘条件。如果在步骤1的第一次迭代期间发现的区域之外找到的曲线之一是完全圆形并且接触外圆,则在“设置Q”内将存在无限点,并且该算法将失败地失败。所以,在第一次应用rgnShape.Intersect(rgnCircle);之后,你应该明确地检查任何完美的圆形曲线。例如,如果您的形状为(},那么如果()位于找到的区域之外,则应明确检查()(出于此讨论的目的,假装(为圆圈)在第一次迭代期间。

    这仍然非常糟糕,但它比将每条曲线更改为点更好。

答案 2 :(得分:0)

你可以在GraphicsPath和Region上使用GetBounds,然后比较矩形的大小,至少让你接近。

如果定义的空格是一个准确的正方形。

如果定义的空间是别的,那至少会让你接近。然后,您可以使用二进制搜索来查找实际的缩放量。

答案 3 :(得分:0)

你不能计算图形路径的中心和半径吗?

你可以计算重心(坐标的平均值)并增加2倍的标准差 - 这应该可以让你获得大约92%的图表 - 大部分时间它会很好,但是如果你的图表最多,它将会失败“重量”在一端。

您还可以计算点的中心 - 遍历所有点,在计算边界框时获取所有方向上的最大/最小点,取此中心并测量到(最大/最小)点的最长距离作为半径

如果你寻找一个边界球体算法,你可能会发现一个更复杂的算法 - 但如果只是为了显示某些东西你可以做一些权衡。如果您正在进行碰撞检测,那么也存在一些快速算法:)

答案 4 :(得分:0)

使用简单的数学怎么样?即,获取路径的边界框/圆,计算预定义的高度/宽度矩形比,将其与BB的相同值进行比较,相应地拉伸BB(例如,如果预定义比率小于1,则BB水平拉伸并且垂直地否则匹配相同的比率),最后将整个事物缩放到预定义的矩形尺寸。比例因子现在只是预定义高度除以BB高度和预定义宽度除以BB宽度之间的最小值。 (对于边界圆,无需调整其大小。)