2016-05-31 72 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