在numpy数组内生成填充的多边形 [英] Generating a filled polygon inside a numpy array

查看:242
本文介绍了在numpy数组内生成填充的多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种基于一组多边形顶点将填充的多边形绘制"为numpy数组的方法.我宁愿使用尽可能少的外部库.

I'm looking for a way to 'draw' a filled polygon into a numpy array based upon a set of polygon vertices. I'd prefer to use as few external libraries as possible.

例如:我有一个20x20的numpy数组,我想要由(3,12),(8,18),(13,14),(11,6)和(4,6)点界定的区域)填充为1.0,而数组的其余部分包含0.0

For example: I have a 20x20 numpy array and I'd like the region bounded by points (3,12), (8,18), (13,14), (11,6) and (4,6) to be filled with 1.0 while the rest of the array contains 0.0

推荐答案

以下解决方案仅需要numpy.它适用于凸多边形的顶点(在[行,列]坐标系中按顺时针顺序定义).凹面多边形可以使用,但最终会切除凸出的点.

The following solution requires only numpy. It works for vertices (defined in clockwise order in [Row, Column] coordinate system) for convex polygons. Concave polygons will work, but will end up cutting off the protruding points.

import numpy as np

def check(p1, p2, base_array):
    """
    Uses the line defined by p1 and p2 to check array of 
    input indices against interpolated value

    Returns boolean array, with True inside and False outside of shape
    """
    idxs = np.indices(base_array.shape) # Create 3D array of indices

    p1 = p1.astype(float)
    p2 = p2.astype(float)

    # Calculate max column idx for each row idx based on interpolated line between two points
    max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) +  p1[1]    
    sign = np.sign(p2[0] - p1[0])
    return idxs[1] * sign <= max_col_idx * sign

def create_polygon(shape, vertices):
    """
    Creates np.array with dimensions defined by shape
    Fills polygon defined by vertices with ones, all other values zero"""
    base_array = np.zeros(shape, dtype=float)  # Initialize your array of zeros

    fill = np.ones(base_array.shape) * True  # Initialize boolean array defining shape fill

    # Create check array for each edge segment, combine into fill array
    for k in range(vertices.shape[0]):
        fill = np.all([fill, check(vertices[k-1], vertices[k], base_array)], axis=0)

    # Set all values inside polygon to one
    base_array[fill] = 1

    return base_array


# (Row, Col) Vertices of Polygon (Defined Clockwise)
vertices = np.array([
    [5,12],
    [8,18],
    [13,14],
    [11,6],
    [4,6],
])

polygon_array = create_polygon([20,20], vertices)

# This section prints numbers at each vertex for visual check, just comment out 
# to print an array of only zeros and ones
for n, vertex in enumerate(vertices):
    polygon_array[vertex[0],vertex[1]] = 10*(n+1)

# Simple routine to print the final array
for row in polygon_array.tolist():
    for c in row:
        print '{:4.1f}'.format(c),
    print ''

这篇关于在numpy数组内生成填充的多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆