2016-05-31 71 views
2

我寫一個程序,它接受用戶輸入以(1)號形狀的邊的要繪製的,(2)如何大繪製它,(3)有多少繪製,和(4)有多少顏色使用。烏龜然後將這些形狀中的許多形狀圍成一個圓圈,所有這些都在圓圈的中心共享一個頂點。控制Python龜的形狀重疊?

有什麼讓我困擾的是,如果形狀在最後重疊,最後的形狀將在一切之上,而我希望它們像其他形狀一樣藏在它們前面的形狀後面。

我已經成功地確定重疊不正確的形狀的數量取決於形狀的邊的數目 - 例如用於一個三角形,有1-6個形狀沒有重疊。 7-12,一個形狀重疊不正確。 13-18,兩個形狀重疊不正確。等等。

到目前爲止,我已經寫了它來考慮形狀的第一組和最後一組作爲他們自己的東西,poly1和poly2,並開始我至少想要能夠告訴它在繪製poly2後面POLY1。

主要的東西:這是甚至可能的烏龜?然後,如果是這樣,我該怎麼做? (使用3.5)

編輯:我想這可能是不可能的。我所聽到的一切都是,龜只能在現有的形狀上畫畫。但也有人建議我加入一張屏幕截圖,以增加清晰度;這裏有一張烏龜畫的圖片(當被告知用三種不同的顏色繪製9個三角形時)。

enter image description here

我的目標是使全三角形一個下夾着在12點,但仍比前一個它,喜歡它最初繪製。

+0

這是因爲'turtle'把每個形狀在最後。你將不得不重繪第一個形狀的一部分來重疊最後一個形狀。 (另外:你的帖子可能並不完全清楚,如果你發佈了一些截圖,這可能會有所幫助) –

回答

1

我想這大概是不可能的。

你低估龜的進取心。這裏是我表現出你希望解決不對稱問題最初的例子:

import math 
from itertools import cycle 
from turtle import Turtle, Screen 

COLORS = cycle(['red', 'green', 'blue', 'yellow']) 

def rotate_polygon(polygon, angle): 

    theta = math.radians(angle) 
    sin, cos = math.sin(theta), math.cos(theta) 

    return [(x * cos - y * sin, x * sin + y * cos) for x, y in polygon] 

def fill_polygon(turtle, polygon, color): 

    turtle.color(color) 

    for vertex in polygon: 
     turtle.goto(vertex) 

     if not turtle.filling(): 
      turtle.begin_fill() 

    turtle.end_fill() 

# triangle cursor 5x in size and X translated 50 pixels 
polygon = ((100, -28.85), (50, 57.75), (0, -28.85)) 

screen = Screen() 

yertle = Turtle(visible=False) 
yertle.penup() 

for angle in range(0, 360, 30): 
    rotated_polygon = rotate_polygon(polygon, angle) 
    color = next(COLORS) 
    fill_polygon(yertle, rotated_polygon, color) 

screen.exitonclick() 

輸出

enter image description here

我們真的希望最終的黃色三角形整齊下初始紅色貼身攜帶,像一個不斷上升的埃舍爾樓梯。我選擇了這個插圖,因爲它有多個重疊,最後的黃色三角不僅在紅色下面,而且在紅色後面是綠色和藍色。同樣,最後的黃色之前的藍色和綠色應低於紅色。等

enter image description here

上面我的代碼要複雜得多,需要吸取這個特殊的示意圖,但需要額外的結構支持以下改進:

一種辦法是制定出路口,而不是畫出最新三角形的那部分。另一種方法是繪製新的三角形,但在應該被遮蓋的三角形交叉點處重新着色。這後一種方法是我實現下,使用現有的Python函數來獲取通過薩瑟蘭-Hodgman多邊形裁剪算法的交集:

import math 
from itertools import cycle 
from turtle import Turtle, Screen 

COLORS = cycle(['red', 'green', 'blue', 'yellow']) 

def clip(subjectPolygon, clipPolygon): 

    # obtain this code from: 
    # https://rosettacode.org/wiki/Sutherland-Hodgman_polygon_clipping#Python 

    return outputList 

def rotate_polygon(polygon, angle): 

    theta = math.radians(angle) 
    sin, cos = math.sin(theta), math.cos(theta) 

    return [(x * cos - y * sin, x * sin + y * cos) for x, y in polygon] 

def fill_polygon(turtle, polygon, color): 

    turtle.color(color) 

    for vertex in polygon: 
     turtle.goto(vertex) 

     if not turtle.filling(): 
      turtle.begin_fill() 

    turtle.end_fill() 

# triangle cursor 5x in size and X translated 50 pixels 
polygon = ((100, -28.85), (50, 57.75), (0, -28.85)) 

screen = Screen() 

yertle = Turtle(visible=False) 
yertle.speed('slowest') # slowly so we can see redrawing 
yertle.penup() 

polygons = [] 
POLYGON, COLOR = 0, 1 

for angle in range(0, 360, 30): 
    rotated_polygon = rotate_polygon(polygon, angle) 
    color = next(COLORS) 
    fill_polygon(yertle, rotated_polygon, color) 
    polygons.append((rotated_polygon, color)) 

    # The -3 here is empirical and really should be calculated, an exercise for the reader 
    for forward, backward in enumerate(range(-3, 1 - len(polygons), -1)): 
     if polygons[forward] != polygons[backward]: 
      try: 
       intersection_polygon = clip(rotated_polygon, polygons[forward][POLYGON]) 
      except (IndexError, ZeroDivisionError): 
       break # because clip() can throw an error when no intersection 

      if intersection_polygon: 
       fill_polygon(yertle, intersection_polygon, polygons[forward][COLOR]) 
      else: 
       break # if no intersection, don't look any further 
     else: 
      break # avoid testing against polygons clockwise from this one (needs work) 

screen.exitonclick() 

輸出

enter image description here