仅使用顶点列表按比例缩放多边形

时间:2015-06-29 21:02:43

标签: python python-2.7 tkinter scaling

在我的程序中,用户可以在matplotlib图上绘制形状,并对这些形状执行各种操作。我现在正试图实现这些形状的缩放,以便在参照主图时保持它们的位置,即使在放大时也是如此。

我的对象由顶点列表

表示
obj = [(1, 1), (2, 1), (1, 0), (2, 0)] # represents a 1 unit square

当然这是我的多边形如何表示的简化细分,但在这种情况下它们唯一有用的属性是顶点。

用户可以选择他想放大的边界框,如下所示

enter image description here

一旦释放鼠标,应用程序将缩放到该位置,唯一的问题是我的多边形不会随此缩放。当画布被缩放时,多边形将保留在它们的确切位置,现在代表与之前完全不同的区域。这是因为缩放由matplotlib处理,matplotlib是实际应用程序的后端。如果用户要放大上面选定的位置,我喜欢要做的就是下图所示: enter image description here

所以我知道的是

  • 对象[(1,2),(1,0)....]
  • 的顶点列表
  • 有界缩放targets = [itemHandle1, itemHandle2....]
  • 中包含的所有对象的句柄列表
  • 通过topleft和right right坐标的有界缩放框的位置,例如zoomboundedbox = [(162, 62), (937, 560)]

我相信我知道有关我的对象的所有必需数据以正确缩放这些对象,但我不知道算法将允许我完成此任务...

def receive(self, lim):
'''
Calculate new coordinates of polygons visible to screen, this function
is called when the user releases the mouse button on the zoom function,
the parameters of the bounding box are internally stored as (x,y) tuples
in xyf (x,y first) and xyl (x,y last)
'''

    # Grab all item handles to polygons that intersect with the zoom
    # Stored in `targets`

    for shape in self.activePolygonList:         # loop through active polygons on screen
        if shape.handle() in targets:            # if the polygon is a target to be scaled
            print "scaling...."
            # ?                                   
            shape.redrawShape()

1 个答案:

答案 0 :(得分:5)

As I said in comment, I think you can use something similar to what I did in my answer to Rotate line around center point given two vertices.

The only difference would be that the mathematical formulas to scale a point (x,y) by a factor of S relative to the point (cx, cy) are:

x_new = (  S * (x - cx) ) + cx
y_new = (  S * (y - cy) ) + cy

And these are what determines how the computation of points (p1x, p1y) and (p2x, p2y) from (x1, y1) and (x2, y2) as done in the inner loop.

Another difference might be that you would want to scale all your polygons relative to the center of the user's bounding box rather than the center of each polygon. That would mean you wouldn't have to compute cx and cy for each polygon (which would make it faster).