基于顶点坐标实现多边形按比例缩小的技术咨询
嘿,这个需求其实挺清晰的——本质就是对多边形的每个顶点做基于中心的比例缩放变换,我给你拆解成可落地的步骤,结合你给的例子一步步来:
核心逻辑
缩放多边形的关键是:先选定一个缩放中心(比如多边形的中心或边界框中心),然后让每个顶点相对于这个中心,按指定的宽高比例缩小/放大,最后计算出新的顶点坐标。
步骤1:确定缩放中心
常见的有两种选择,按需选就行:
- 边界框中心:计算最简单,适合快速处理,就是多边形所有顶点的x范围中点和y范围中点
- 多边形重心(几何中心):更贴合不规则多边形的实际中心,计算稍复杂但更精准
边界框中心计算
拿你给的顶点列表举例:
- 提取所有x坐标:
[0,0,20,30,40,60,60,40,40,20,20]→ 最小x=0,最大x=60 → 中心x=(0+60)/2=30 - 提取所有y坐标:
[0,100,100,60,100,100,0,10,40,40,10]→ 最小y=0,最大y=100 → 中心y=(0+100)/2=50 - 最终边界框中心为
(30, 50)
多边形重心计算(精准版)
如果需要更精准的几何中心,可以用多边形重心公式(适用于简单多边形,凸/凹都可):
def calculate_polygon_centroid(vertices): n = len(vertices) area = 0.0 centroid_x = 0.0 centroid_y = 0.0 for i in range(n): x_i, y_i = vertices[i] x_j, y_j = vertices[(i+1)%n] # 下一个顶点,循环到第一个 cross_product = x_i * y_j - x_j * y_i area += cross_product centroid_x += (x_i + x_j) * cross_product centroid_y += (y_i + y_j) * cross_product area *= 0.5 centroid_x /= (6 * area) centroid_y /= (6 * area) return (round(centroid_x, 2), round(centroid_y, 2))
代入你的顶点,计算出的重心大概是(30.0, 48.18)(和边界框中心略有差异)
步骤2:确定缩放因子
你说的“缩小10%”对应x方向的缩放因子是0.9(保留原尺寸的90%),“缩小20%”对应y方向的缩放因子是0.8。如果是放大,因子就大于1(比如放大50%就是1.5)。
步骤3:计算每个新顶点的坐标
对每个顶点,用以下公式计算新坐标:
新x = 缩放中心x + (原顶点x - 缩放中心x) * x缩放因子 新y = 缩放中心y + (原顶点y - 缩放中心y) * y缩放因子
示例计算(边界框中心)
拿第一个顶点(0,0)举例:
新x = 30 + (0-30)*0.9 = 30 -27 = 3
新y =50 + (0-50)*0.8 =50-40=10
→ 新顶点为(3,10)
再拿顶点(30,60)举例:
新x=30 + (30-30)*0.9=30
新y=50 + (60-50)*0.8=50+8=58
→ 新顶点为(30,58)
完整实现代码(Python)
这里用边界框中心做示例,你可以替换成重心版本:
def scale_polygon(vertices, scale_x, scale_y): # 计算边界框中心 x_coords = [x for x, y in vertices] y_coords = [y for x, y in vertices] center_x = (min(x_coords) + max(x_coords)) / 2 center_y = (min(y_coords) + max(y_coords)) / 2 scaled_vertices = [] for x, y in vertices: new_x = center_x + (x - center_x) * scale_x new_y = center_y + (y - center_y) * scale_y scaled_vertices.append((round(new_x, 2), round(new_y, 2))) return scaled_vertices # 你的原始顶点 original_vertices = [(0, 0), (0, 100), (20, 100), (30, 60), (40, 100), (60, 100), (60, 0), (40, 10), (40, 40), (20, 40), (20, 10)] # 执行缩放:x缩小10%(因子0.9),y缩小20%(因子0.8) scaled_result = scale_polygon(original_vertices, 0.9, 0.8) print("缩放后的顶点坐标:") for point in scaled_result: print(point)
注意事项
- 这个方法对凸多边形和凹多边形都有效,不会改变多边形的拓扑结构
- 如果需要以某个特定点(比如原点
(0,0))为中心缩放,直接把center_x和center_y设为该点即可,公式简化为new_x = x*scale_x,new_y = y*scale_y - 缩放因子如果是负数,会让多边形在对应轴上翻转,一般缩小用0到1之间的正数就行
内容的提问来源于stack exchange,提问作者TheStrangeQuark
相关产品推荐
相关产品推荐

