簡體   English   中英

如何填充matplotlib中兩條弧線和兩條線段之間的空間?

[英]How to fill the space between two arcs and two segments in matplotlib?

我知道這種問題已經發布了好幾次了,但是在你做任何決定之前先聽我說完。

簡而言之,我想把這個:

在此處輸入圖像描述

進入這個:

在此處輸入圖像描述

所有曲線都是圓的六分之一,三條折線近似於螺旋的三個臂,我需要填充由兩個臂和兩個弧定義的所有區域。

我在這個站點上查看了一堆處理類似問題的問題,都提到ax.fill_between方法,但它涉及 NumPy 數組,我沒有使用 NumPy 數組進行計算。

計算事物的函數如下(減去邊界框部分):

def polygon_spiral(unit, iterations, num_colors=12):
    step = 1530/num_colors
    palette = ['#'+spectrum_position(round(step*i), 1) for i in range(num_colors)]
    colors = [palette[0]]
    radius = unit*cos(30)/1.5
    y1 = -radius/2
    x1 = -unit/2
    x2 = unit/2
    points = [(0, radius), (x2, y1), (x1, y1)]
    polygons = [points]
    lines = [[(0, 0), (x1/2, radius/4)], [(0, 0), (0, y1)], [(0, 0), (x2/2, radius/4)]]
    side = 4
    left_start, left_end = points[0], points[2]
    down_start, down_end = points[2], points[1]
    right_start, right_end = points[1], points[0]
    for i in range(iterations):
        left = make_polygon(left_start, left_end, side)
        down = make_polygon(down_start, down_end, side)
        right = make_polygon(right_start, right_end, side)
        polygons.append(left)
        polygons.append(down)
        polygons.append(right)
        colors.extend([palette[(i+1)%num_colors]]*3)
        half = (side/2).__ceil__()
        left_start, left_end = left[half-1:half+1]
        lines[0].append(mid(left_start, left_end))
        down_start, down_end = down[half-1:half+1]
        lines[1].append(mid(down_start, down_end))
        right_start, right_end = right[half-1:half+1]
        lines[2].append(mid(right_start, right_end))
        side += 1

    indices = {0: (1, 2), 1: (0, 2), 2: (0, 1)}
    arcs = []
    for i in range(iterations+1, 0, -1):
        points = [lines[j][i] for j in range(3)]
        (x0, y0), (x1, y1), (x2, y2) = points
        dx = x1 - x0
        dy = y1 - y0
        r = (dx*dx + dy*dy)**.5
        
        for k, v in indices.items():
            a, b = points[k]
            thetas = []
            for h in v:
                c, d = points[h]
                angle = atan2(c - a, d - b)
                if angle < 0:
                    angle += 360
                thetas.append(angle)
            theta1, theta2 = thetas
            if theta1 > theta2:
                theta1, theta2 = theta2, theta1
            if not np.isclose(theta2 - theta1, 60):
                theta1, theta2 = theta2 - 360, theta1
            arcs.append([(a, b), r, theta1, theta2])
    
    return {'polygons': polygons, 'lines': lines, 'arcs': arcs, 'colors': colors}

您可以在GitHub 上查看完整的腳本。

關鍵是線條存儲為三個離散頂點的坐標list (存儲為(x, y) tuple s),它們是通過matplotlib.collections.LineCollection繪制的,弧由其中心的坐標描述,它的半徑,theta1 和 theta2,並通過matplotlib.patches.Arc繪制。

我沒有在這個腳本的任何地方使用數組,如何在不使用數組和fill_between的情況下填充由兩個弧和兩個臂定義的區域,如果這不可能,我如何以矢量化方式進行相同的計算並使用fill_between來填充區域?

我又解決了。

在此處輸入圖像描述

基本上,我使用多邊形填充了這些區域。

每個區域由四條線、兩條直線和兩條弧線包圍。 兩條弧跨度為 60°。

arcs list ,包圍該區域的外圓弧和內圓弧的索引相差 3。

所以我取了每對索引差為 3 的弧,並用它們制作了一個多邊形。

我是如何制作多邊形的?

弧跨度為 60°,我在第一個弧上采樣了 61 個點,每對相鄰點有 1° 的角度差,在另一個方向上在第二個弧上采樣了 61 個點:

L = len(arcs)
for i in range(3):
    level = 0
    for first, second in zip(arcs[i:L:3], arcs[i+3:L:3]):
        f = 1 - level / iterations
        r, g, b = colorsys.hsv_to_rgb(hues[i], f, f)
        strip_colors.append('#{:02x}{:02x}{:02x}'.format(round(r*255), round(g*255), round(b*255)))
        vertices = []
        (a, b), r, theta1, theta2 = first
        for n in range(61):
            angle = theta1+n
            vertices.append((a+r*cos(angle), b+r*sin(angle)))
        (a, b), r, theta1, theta2 = second
        for n in range(61):
            angle = theta2-n
            vertices.append((a+r*cos(angle), b+r*sin(angle)))
        strips.append(vertices)
        level += 1

完整的代碼在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM