优雅的大蟒蛇——Pythonprogram

turtle模块中的position问题

2018-03-12  本文已影响0人  帕博雷克斯丢丢

问题是这样的,最近无意中看到一小段代码如下:

from turtle import *
color('red', 'yellow')
begin_fill()
while True:
    speed(10)
    forward(200)
    left(170)
    if abs(pos()) < 1:
        break
end_fill()
done()

这段代码用来画出一个并不怎么好看的图形

turtle_painting.JPG

这些都不是重点,咳咳……


可以看到第8行代码if abs(pos()) < 1:当时很奇怪,因为pos()函数的返回值是一个二维坐标,为什么能对它进行取绝对值运算呢?

对tuple进行abs()操作会报错.JPG

可以看到pos()的返回值是turtle.Vec2D类型

photo0001.JPG
photo0002.JPG

但是!Vec2D也是tuple类型啊,为什么会这样?

不信你看源码:

class Vec2D(tuple):
    """A 2 dimensional vector class, used as a helper class
    for implementing turtle graphics.
    May be useful for turtle graphics programs also.
    Derived from tuple, so a vector is a tuple!

    Provides (for a, b vectors, k number):
       a+b vector addition
       a-b vector subtraction
       a*b inner product
       k*a and a*k multiplication with scalar
       |a| absolute value of a
       a.rotate(angle) rotation
    """
    def __new__(cls, x, y):
        return tuple.__new__(cls, (x, y))
    def __add__(self, other):
        return Vec2D(self[0]+other[0], self[1]+other[1])
    def __mul__(self, other):
        if isinstance(other, Vec2D):
            return self[0]*other[0]+self[1]*other[1]
        return Vec2D(self[0]*other, self[1]*other)
    def __rmul__(self, other):
        if isinstance(other, int) or isinstance(other, float):
            return Vec2D(self[0]*other, self[1]*other)
    def __sub__(self, other):
        return Vec2D(self[0]-other[0], self[1]-other[1])
    def __neg__(self):
        return Vec2D(-self[0], -self[1])
    def __abs__(self):
        return (self[0]**2 + self[1]**2)**0.5
    def rotate(self, angle):
        """rotate self counterclockwise by angle
        """
        perp = Vec2D(-self[1], self[0])
        angle = angle * math.pi / 180.0
        c, s = math.cos(angle), math.sin(angle)
        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
    def __getnewargs__(self):
        return (self[0], self[1])
    def __repr__(self):
        return "(%.2f,%.2f)" % self

哈哈哈哈,原来啊,Vec2D是个用来表示向量的类型,对它进行abs()操作其实就是对这个向量取模,源码中已经说明了abs(pos())是怎样一种骚操作:

def __abs__(self):
        return (self[0]**2 + self[1]**2)**0.5
上一篇下一篇

猜你喜欢

热点阅读