pythonでペンローズの三角形を描いてみた

pythonでペンローズの三角形を描いてみた

import cv2
import numpy as np
import math
import time

canvas_x=1300
canvas_y=800

#  0:black  1:gray  2:silver  3:white  4:blue     5:navy   6:teal      7:green
#  8:lime   9:aqua 10:yellow 11:red   12:fuchsia 13:olive  14:purple  15:maroon
colorindex=[(0,0,0),(128,128,128),(192,192,192),(255,255,255),(255,0,0),(128,0,0),(128,128,0),(0,128,0),(0,255,0),(255,255,0),(0,255,255),(0,0,255),(255,0,255),(0,128,128),(128,0,128),(0,0,128)]


def zahyohenkan(x,y):
    return int(x+canvas_x/2),int(-y+canvas_y/2)

def put_tri(img,x,y,BGR):
    # 13x12
    d=40
    d0=2*d/3**0.5    #正三角形の辺の半分
    x0 = int(0 + (x ) * d * 2)
    y0 = int(-d0 + (y + 1) * d0)
    if (x+y)%2==0:
        #  ◁

        pts = np.array((
                        (int(x0 + d), int(y0 - d0)),
                        (int(x0 - d), y0 ),
                        (int(x0 + d), int(y0 +d0))
        ))
    else:
        #  ▷
        pts = np.array((
                        (int(x0 - d), int(y0 - d0)),
                        (int(x0 + d), y0 ),
                        (int(x0 - d), int(y0 +d0))
        ))

    cv2.fillPoly(img, [pts], BGR)

def put_tri2(img,x,y,BGR):
    d=50
    d0=2*d/3**0.5    #正三角形の辺の半分
    x0 = int(0 + (x ) * d * 2)
    y0 = int(-d0 + (y + 2) * d0)
    if (x+y)%2==0:
        #  ▽
        pts = np.array((
                        (x0 - int(d0), y0 - d),
                        (x0 + int(d0), y0 - d),
                        (x0 , y0 +d)
        ))
    else:
        #  △
        pts = np.array((
                        (x0 - int(d0), y0 + d),
                        (x0 + int(d0), y0 + d),
                        (x0 , y0 -d)
        ))

    cv2.fillPoly(img, [pts], BGR)

def pset(img,a,s1,s2):
    for y in range(len(a)):
        for x in range(len(a[y])):
            #print(a[y][x])
            put_tri(img, x, y, colorindex[int(a[y][x])])
            if s1>0:
                cv2.imshow('OpenCV', img)
                cv2.waitKey(int(s1*1000))
    cv2.imshow('OpenCV', img)
    cv2.waitKey(int(s2 * 1000))

def Penrose1(img,a):
    #ペンローズの三角形1
    s2=0.2
    a[3][10] = 8
    a[4][10] = 7
    for i in range(5,0,-1):
        a[8-i][4+i] = 8
        a[9 - i][4 + i] = 8
        a[10- i][5 + i] = 7
        a[10- i][4 + i] = 7
        pset(img, a, 0.00, s2)
    a[8][4] = 8
    a[9][4] = 9
    for i in range(0,6,1):
        a[8+i][5+i] = 8
        a[9 + i][5 + i] = 8
        a[10+ i][5 + i] = 9
        a[10+ i][4 + i] = 9
        pset(img, a, 0.00, s2)
    a[16][10] = 9
    a[16][11] = 7
    for i in range(0,10,1):
        a[15- i][10] = 9
        a[15- i][11] = 7
        pset(img, a, 0.00, s2)
    a[5][11] = 7
    a[4][11] = 7
    pset(img, a, 0.00, s2)
    a[3][11] = 7
    a[2][10] = 8
    a[2][11] = 8
    pset(img, a, 0.00, s2)

def Penrose2(img,a,c,s2):
    #c=[11,10,4,9,7]   #赤黄青水緑
    for i in range(0,6,1):
        if i>0:
            a[15 - i][10- i] = c[(i+1) % 4]
            a[16 - i][10- i] = c[(i+1) % 4]
            a[14 - i][10- i] = c[(i+1) % 4]
            a[14 - i][11- i] = c[(i+1) % 4]
        a[16- i*2][10] = c[i%4]
        a[16- i*2][11] = c[i%4]
        a[15- i*2][10] = c[i%4]
        a[15- i*2][11] = c[i%4]
        pset(img, a, 0.00, s2)
    c = np.roll(c, 2)
    a[9 ][4] = c[0]
    a[10][4] = c[0]
    for i in range(0, 7, 1):
        a[8 - i][5 + i] = c[i % 4]
        a[8 - i][4+i] = c[i % 4]
        if i>0:
            a[9 - i][5+i] = c[i % 4]
            if i != 1:
                a[10 - i][5+i] = c[i % 4]
        pset(img, a, 0.00, s2)

def mapex(a,c1,c2):
    b=a
    for y in range(len(b)):
        for x in range(len(b[y])):
            if b[y][x]==c1:
                b[y][x]=c2
    return b


def main():
    img = np.full((canvas_y, canvas_x, 3), 255, dtype=np.uint8)

    a = np.zeros((19, 17))   #白紙状態にする
    pset(img,a,0.00,1)


    Penrose1(img, a)
    time.sleep(3)
    c = [11, 10, 4, 9, 7]  # 赤黄青水緑
    Penrose2(img, a,c,0.2)
    time.sleep(2)

    s2 = 1
    for t in range(30):
        for i in range(len(c)):
            if i==0:
                a = mapex(a, c[(t+i)%len(c)], -c[(t+i)%len(c)])
            a = mapex(a, c[(t+i)%len(c)], c[(t+i-1)%len(c)])
            if i==len(c)-1:
                a = mapex(a, -c[(t+0)%len(c)], c[(t+i)%len(c)])
        pset(img, a, 0.00, 0.3)

    cv2.imshow('OpenCV', img)
    cv2.waitKey(15000)
    #cv2.destroyAllWindows()


main()