彭罗斯瓷砖的python实现

彭罗斯瓷砖的python实现


由于做图形学学python,openmesh库的一些实现形式,了解到彭罗斯瓷砖这个很秀的东西 (彭罗斯瓷砖科普),我就试试用下面这个风筝和飞镖的模型写代码生成一个。

肯定是先明白他的连接方式,我研究了一下他有这样的几个特性:
1.飞镖和风筝都有四条边
2.每条边都会连接另一条等长的边
3.根据那个蓝色圆圈和红色圆圈要连接上我发现有以下几种连接方式:


然后看着就如果知道各个点的坐标,根据每一条边来不断随机扩展就可以了,但是这可能会出现形状重合的冲突,这我还没想明白怎么弄,但我决定先编程看看生成以下扩展。
在这里插入图片描述
观察一下就可以看出来这个风筝可以看做是由两个等腰三角形拼接的,所以各个角度各个坐标都可以很轻松的算出来。我们把最上面的点看做是第一个点,逆时针转一次是234点,可以得到这个坐标:

a = (5**0.5+1)/2   #黄金分割1.6      
beta = np.arccos( (5**0.5+1)    /   (2*5**0.5 + 6))  #风筝测角
alpha = np.pi*2-4*beta   #风筝顶角
# 初始化一个风筝-----------------------------------
x1 = 0
y1 = a*np.cos(beta)
x2 = -a*np.sin(beta)
y2 = 0
x3 = 0
y3 = y1-(1+a)
x4 = a*np.sin(beta)
y4 = 0

其他的风筝和飞镖也用这种顺序标定点的序号,边的话就1、2两点间是第一条边以此类推。我先决定把这个风筝先生成出来,这就很简单了:

xlist = [x1,x2,x3,x4,x1]
ylist = [y1,y2,y3,y4,y1]
plt.plot(xlist,ylist)

mesh = om.TriMesh()
vhandle = []
vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))
face_vhandles = []
face_vhandles.append(vhandle[0])
face_vhandles.append(vhandle[1])
face_vhandles.append(vhandle[2])
face_vhandles.append(vhandle[3])
mesh.add_face(face_vhandles)

plt.show()
om.write_mesh("./penrose.obj", mesh)

用plot和mesh两种办法展示是因为反正是一个二维平面,而且mesh生成的表面是光滑的没有间隙没有边框的图形,看不出来是怎么拼接的,所以plot用来观察是很方便的,但是最终目的是生成mesh,所以mesh也得生成着走一步调一步免得出bug。
生成了一个就要考虑怎么去无限生成更多的。我的思路是一条边一条边的扩展,也就是用一个递归来实现。
先得到这个图形的四条边的坐标,存入变量edgex和edgey,然后还要有一个数组isextend存储 这四条边是否被扩展了,因为已经扩展的就不需要再被扩展了,而且刚扩展出来的四边形也只有新生成的几条边需要去继续扩展,这条母边不需要扩展。

edgex = []#用来存点的x坐标
edgey = []#用来存点的x坐标
isextend = []#存是否扩展了
edgex.append([x1,x2,x3,x4])
edgey.append([y1,y2,y3,y4])
isextend.append([0,0,0,0])
digui(edgex[-1],edgey[-1],isextend[-1],1,0)

digui这个函数中前三个变量就是刚才说的,还引入了两个参数,倒数第二个的作用是控制我们的递归递归多少次,最后一个的作用是传入我正在进行扩展的这个图形是风筝0还是飞镖1,。
我用风筝来先进行扩展第一条边扩展一个风筝来讲解我的递归思路:
先上代码:

def digui(x,y,isextendnow,mynum,thistype):
    n = 3  #用来控制迭代几次
    if thistype == 0 : #如果是风筝要扩展
        for i in range(len(isextendnow)):  #查看每一条边
            if isextendnow[i] == 0 :       #如果这个边没被扩展需要被扩展
                if i == 0:                 #第一条
                    #扩展个风筝
                    x1 = x[0]
                    y1 = y[0]
                    x2= (x[1]-x[0])*np.cos(2*beta) + (y[1]-y[0])*np.sin(2*beta)+x[0]
                    y2 = (y[1]-y[0])*np.cos(2*beta) - (x[1]-x[0])*np.sin(2*beta)+y[0]
                    x3= (x[2]-x[0])*np.cos(2*beta) + (y[2]-y[0])*np.sin(2*beta)+x[0]
                    y3 = (y[2]-y[0])*np.cos(2*beta) - (x[2]-x[0])*np.sin(2*beta)+y[0]
                    x4 = x[1]
                    y4 = y[1]
                    #扩展个标枪
                    #x1 = x[1]
                    #y1 = y[1]
                    #x2= x[0]
                    #y2 = y[0]
                    #x3 = (x[2]-x[1])*np.cos(np.pi) + (y[2]-y[1])*np.sin(np.pi)+x[1]
                    #x3 = (a+1-2*a*np.cos(beta))*x3/(a+1) + 2*a*np.cos(beta)*x[1]/(a+1)
                    #y3 = (y[2]-y[1])*np.cos(np.pi) - (x[2]-x[1])*np.sin(np.pi)+y[1]
                    #y3 = (a+1-2*a*np.cos(beta))*y3/(a+1) + 2*a*np.cos(beta)*y[1]/(a+1)
                    #x4= (x[0]-x[1])*np.cos(2*beta) + (y[0]-y[1])*np.sin(2*beta)+x[1]
                    #y4 = (y[0]-y[1])*np.cos(2*beta) - (x[0]-x[1])*np.sin(2*beta)+y[1]

                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)           #绘制

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[0] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    # isextend.append([0,0,0,1])
                    isextend.append([1,0,0,0]) #飞镖
                    if mynum < n :       #控制次数递归
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归

对这个边的扩展主要是找到这样扩展的风筝的四个坐标在哪里,并且画出来存进edgex,edgey,还要更新当前isextend和刚扩展出来的isextend的值,进行下一次递归。
所以这一步的主要就是寻找扩展出来的风筝的四个坐标在哪里,我的思路主要是用齐次坐标进行旋转后得到。因为我看到,无论是哪种连接方式,新图形的四条边都可以由原图形的四条边旋转、伸缩后得到,而且角度和伸缩比例是我们已知的,就拿风筝在第二条边扩展飞镖来看:

在这里插入图片描述

飞镖4点可以由风筝点2绕风筝点1旋转得到,飞镖1点可以由风筝点2绕风筝点1旋转伸缩得到,且飞镖2、3点都是风筝原2、1点,这样就可以得到新的四个坐标。
用这样的办法可以得到图形扩展新图形后的坐标,用递归可以一直重复下去。但是什么时候生成什么样的图形?怎样造成图形间不冲突不重叠,因为平铺的要求就是无缝隙、不重叠,这个似乎可以通过添加一些规则来实现,但是这规则又不少,感觉是个力气活。
到目前为止的源码:

import numpy as np
import openmesh as om
import matplotlib.pyplot as plt
kite = 0
javelin = 1  #C语言遗留宏定义习惯
a = (5**0.5+1)/2   #黄金分割1.6      
beta = np.arccos( (5**0.5+1)    /   (2*5**0.5 + 6))  #风筝测角
alpha = np.pi*2-4*beta   #风筝顶角

def digui(x,y,isextendnow,mynum,thistype):
    n = 3  #用来控制迭代几次
    if thistype == 0 : #如果是风筝要扩展
        for i in range(len(isextendnow)):  #查看每一条边
            if isextendnow[i] == 0 :       #如果这个边没被扩展需要被扩展
                if i == 0:                 #第一条
                    #扩展个风筝
                    x1 = x[0]
                    y1 = y[0]
                    x2= (x[1]-x[0])*np.cos(2*beta) + (y[1]-y[0])*np.sin(2*beta)+x[0]
                    y2 = (y[1]-y[0])*np.cos(2*beta) - (x[1]-x[0])*np.sin(2*beta)+y[0]
                    x3= (x[2]-x[0])*np.cos(2*beta) + (y[2]-y[0])*np.sin(2*beta)+x[0]
                    y3 = (y[2]-y[0])*np.cos(2*beta) - (x[2]-x[0])*np.sin(2*beta)+y[0]
                    x4 = x[1]
                    y4 = y[1]
                    #扩展个标枪
                    x1 = x[1]
                    y1 = y[1]
                    x2= x[0]
                    y2 = y[0]
                    x3 = (x[2]-x[1])*np.cos(np.pi) + (y[2]-y[1])*np.sin(np.pi)+x[1]
                    x3 = (a+1-2*a*np.cos(beta))*x3/(a+1) + 2*a*np.cos(beta)*x[1]/(a+1)
                    y3 = (y[2]-y[1])*np.cos(np.pi) - (x[2]-x[1])*np.sin(np.pi)+y[1]
                    y3 = (a+1-2*a*np.cos(beta))*y3/(a+1) + 2*a*np.cos(beta)*y[1]/(a+1)
                    x4= (x[0]-x[1])*np.cos(2*beta) + (y[0]-y[1])*np.sin(2*beta)+x[1]
                    y4 = (y[0]-y[1])*np.cos(2*beta) - (x[0]-x[1])*np.sin(2*beta)+y[1]

                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)           #绘制

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[0] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    # isextend.append([0,0,0,1])
                    isextend.append([1,0,0,0]) #飞镖
                    if mynum < n :       #控制次数递归
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归
                    
                if i == 1:                  #如果是第二条
                    x1 = (x[0]-x[2])*np.cos(-alpha) + (y[0]-y[2])*np.sin(-alpha)+x[2]
                    y1 = (y[0]-y[2])*np.cos(-alpha) - (x[0]-x[2])*np.sin(-alpha)+y[2]
                    x2= (x[1]-x[2])*np.cos(-alpha) + (y[1]-y[2])*np.sin(-alpha)+x[2]
                    y2 = (y[1]-y[2])*np.cos(-alpha) - (x[1]-x[2])*np.sin(-alpha)+y[2]
                    x3 = x[2]
                    y3 = y[2]
                    x4 = x[1]
                    y4 = y[1]
                    #加个标枪
                    # x1 = (x[2]-x[1])*np.cos(alpha/2) + (y[2]-y[1])*np.sin(alpha/2)+x[1]
                    # x1 = (a+1-2*a*np.cos(beta))*x1/(a+1)+2*a*np.cos(beta)*x[1]/(a+1)
                    # y1 = (y[2]-y[1])*np.cos(alpha/2) - (x[2]-x[1])*np.sin(alpha/2)+y[1]
                    # y1 = (a+1-2*a*np.cos(beta))*y1/(a+1)+2*a*np.cos(beta)*y[1]/(a+1)
                    # x2= x[2]
                    # y2 = y[2]
                    # x3 = x[1]
                    # y3 = y[1]
                    # x4= (x[2]-x[1])*np.cos(alpha) + (y[2]-y[1])*np.sin(alpha)+x[1]
                    # y4 = (y[2]-y[1])*np.cos(alpha) - (x[2]-x[1])*np.sin(alpha)+y[1]

                    
                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[1] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,0,1,0])
                    if mynum < n :
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,0)#回去递归
                if i == 2:                  #如果是第三条
                    #加个风筝
                    x1 = (x[0]-x[2])*np.cos(alpha) + (y[0]-y[2])*np.sin(alpha)+x[2]
                    y1 = (y[0]-y[2])*np.cos(alpha) - (x[0]-x[2])*np.sin(alpha)+y[2]
                    x2 = x[3]
                    y2 = y[3]
                    x3 = x[2]
                    y3 = y[2]
                    x4= (x[3]-x[2])*np.cos(alpha) + (y[3]-y[2])*np.sin(alpha)+x[2]
                    y4 = (y[3]-y[2])*np.cos(alpha) - (x[3]-x[2])*np.sin(alpha)+y[2]
                    #加个标枪
                    # x1 = (x[2]-x[3])*np.cos(-alpha/2) + (y[2]-y[3])*np.sin(-alpha/2)+x[3]
                    # x1 = (a+1-2*a*np.cos(beta))*x1/(a+1)+2*a*np.cos(beta)*x[3]/(a+1)
                    # y1 = (y[2]-y[3])*np.cos(-alpha/2) - (x[2]-x[3])*np.sin(-alpha/2)+y[3]
                    # y1 = (a+1-2*a*np.cos(beta))*y1/(a+1)+2*a*np.cos(beta)*y[3]/(a+1)
                    # x2= (x[2]-x[3])*np.cos(-alpha) + (y[2]-y[3])*np.sin(-alpha)+x[3]
                    # y2 = (y[2]-y[3])*np.cos(-alpha) - (x[2]-x[3])*np.sin(-alpha)+y[3]
                    # x3 = x[3]
                    # y3 = y[3]
                    # x4= x[2]
                    # y4 = y[2]

                    
                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[2] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,1,0,0])
                    if mynum < n :
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,0)#回去递归



                if i == 3:      
                    x1 = x[0]
                    y1 = y[0]
                    x2 = x[3]
                    y2 = y[3]
                    x3= (x[2]-x[0])*np.cos(-2*beta) + (y[2]-y[0])*np.sin(-2*beta)+x[0]
                    y3 = (y[2]-y[0])*np.cos(-2*beta) - (x[2]-x[0])*np.sin(-2*beta)+y[0]
                    x4= (x[3]-x[0])*np.cos(-2*beta) + (y[3]-y[0])*np.sin(-2*beta)+x[0]
                    y4 = (y[3]-y[0])*np.cos(-2*beta) - (x[3]-x[0])*np.sin(-2*beta)+y[0]
                    #加个标枪
                    x1 = x[3]
                    y1 = y[3]
                    x2= (x[0]-x[3])*np.cos(-2*beta) + (y[0]-y[3])*np.sin(-2*beta)+x[3]
                    y2 = (y[0]-y[3])*np.cos(-2*beta) - (x[0]-x[3])*np.sin(-2*beta)+y[3]
                    x3 = (x[2]-x[3])*np.cos(np.pi) + (y[2]-y[3])*np.sin(np.pi)+x[3]
                    x3 = (a+1-2*a*np.cos(beta))*x3/(a+1) + 2*a*np.cos(beta)*x[3]/(a+1)
                    y3 = (y[2]-y[3])*np.cos(np.pi) - (x[2]-x[3])*np.sin(np.pi)+y[3]
                    y3 = (a+1-2*a*np.cos(beta))*y3/(a+1) + 2*a*np.cos(beta)*y[3]/(a+1)
                    x4= x[0]
                    y4 = y[0]

                    
                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[0] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    # isextend.append([1,0,0,0])
                    isextend.append([0,0,0,1]) #飞镖
                    if mynum < n :
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归    


#-------------------------------------------------如果传进来的是飞镖-------------------------------------------------

    if thistype == 1:
        for i in range(len(isextendnow)):  #查看每一条边
            if isextendnow[i] == 0 :       #如果这个边没被扩展
                if i == 0:                 #如果是第一条
                    #加个风筝
                    x1 = x[0]
                    y1 = y[0]
                    x2= (x[1]-x[0])*np.cos(2*beta) + (y[1]-y[0])*np.sin(2*beta)+x[0]
                    y2 = (y[1]-y[0])*np.cos(2*beta) - (x[1]-x[0])*np.sin(2*beta)+y[0]
                    x3= (x[2]-x[0])*np.cos(2*beta) + (y[2]-y[0])*np.sin(2*beta)+x[0]
                    y3 = (y[2]-y[0])*np.cos(2*beta) - (x[2]-x[0])*np.sin(2*beta)+y[0]
                    x4 = x[1]
                    y4 = y[1]
                    #加个标枪
                    x1 = x[1]
                    y1 = y[1]
                    x2= x[0]
                    y2 = y[0]
                    x3 = (x[2]-x[1])*np.cos(np.pi) + (y[2]-y[1])*np.sin(np.pi)+x[1]
                    x3 = (a+1-2*a*np.cos(beta))*x3/(a+1) + 2*a*np.cos(beta)*x[1]/(a+1)
                    y3 = (y[2]-y[1])*np.cos(np.pi) - (x[2]-x[1])*np.sin(np.pi)+y[1]
                    y3 = (a+1-2*a*np.cos(beta))*y3/(a+1) + 2*a*np.cos(beta)*y[1]/(a+1)
                    x4= (x[0]-x[1])*np.cos(2*beta) + (y[0]-y[1])*np.sin(2*beta)+x[1]
                    y4 = (y[0]-y[1])*np.cos(2*beta) - (x[0]-x[1])*np.sin(2*beta)+y[1]

                    # xlist = [x1,x2,x3,x4,x1]
                    # ylist = [y1,y2,y3,y4,y1]
                    # plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[0] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,0,0,1])
                    # if mynum < n :
                        # digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归
                    
                if i == 1:                  #如果是第二条
                    x1 = (x[2]-x[1])*np.cos(alpha/2) + (y[2]-y[1])*np.sin(alpha/2)+x[1]
                    y1 = (y[2]-y[1])*np.cos(alpha/2) - (x[2]-x[1])*np.sin(alpha/2)+y[1]
                    x2 = x[2]
                    y2 = y[2]
                    x3 = x[1]
                    y3 = y[1]
                    x4 = (x[2]-x[1])*np.cos(alpha) + (y[2]-y[1])*np.sin(alpha)+x[1]
                    y4 = (y[2]-y[1])*np.cos(alpha) - (x[2]-x[1])*np.sin(alpha)+y[1]
                    #加个标枪
                    # x1 = (x[2]-x[1])*np.cos(alpha/2) + (y[2]-y[1])*np.sin(alpha/2)+x[1]
                    # x1 = (a+1-2*a*np.cos(beta))*x1/(a+1)+2*a*np.cos(beta)*x[1]/(a+1)
                    # y1 = (y[2]-y[1])*np.cos(alpha/2) - (x[2]-x[1])*np.sin(alpha/2)+y[1]
                    # y1 = (a+1-2*a*np.cos(beta))*y1/(a+1)+2*a*np.cos(beta)*y[1]/(a+1)
                    # x2= x[2]
                    # y2 = y[2]
                    # x3 = x[1]
                    # y3 = y[1]
                    # x4= (x[2]-x[1])*np.cos(alpha) + (y[2]-y[1])*np.sin(alpha)+x[1]
                    # y4 = (y[2]-y[1])*np.cos(alpha) - (x[2]-x[1])*np.sin(alpha)+y[1]

                    
                    xlist = [x1,x2,x3,x4,x1]
                    ylist = [y1,y2,y3,y4,y1]
                    plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[1] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,1,0,0])
                    if mynum < n :
                        digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,0)#回去递归
                if i == 2:                  #如果是第三条
                    #加个风筝
                    x1 = (x[0]-x[2])*np.cos(alpha) + (y[0]-y[2])*np.sin(alpha)+x[2]
                    y1 = (y[0]-y[2])*np.cos(alpha) - (x[0]-x[2])*np.sin(alpha)+y[2]
                    x2 = x[3]
                    y2 = y[3]
                    x3 = x[2]
                    y3 = y[2]
                    x4= (x[3]-x[2])*np.cos(alpha) + (y[3]-y[2])*np.sin(alpha)+x[2]
                    y4 = (y[3]-y[2])*np.cos(alpha) - (x[3]-x[2])*np.sin(alpha)+y[2]
                    #加个标枪
                    x1 = (x[2]-x[3])*np.cos(-alpha/2) + (y[2]-y[3])*np.sin(-alpha/2)+x[3]
                    x1 = (a+1-2*a*np.cos(beta))*x1/(a+1)+2*a*np.cos(beta)*x[3]/(a+1)
                    y1 = (y[2]-y[3])*np.cos(-alpha/2) - (x[2]-x[3])*np.sin(-alpha/2)+y[3]
                    y1 = (a+1-2*a*np.cos(beta))*y1/(a+1)+2*a*np.cos(beta)*y[3]/(a+1)
                    x2= (x[2]-x[3])*np.cos(-alpha) + (y[2]-y[3])*np.sin(-alpha)+x[3]
                    y2 = (y[2]-y[3])*np.cos(-alpha) - (x[2]-x[3])*np.sin(-alpha)+y[3]
                    x3 = x[3]
                    y3 = y[3]
                    x4= x[2]
                    y4 = y[2]

                    
                    # xlist = [x1,x2,x3,x4,x1]
                    # ylist = [y1,y2,y3,y4,y1]
                    # plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[2] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,1,0,0])
                    # if mynum < n :
                        # digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归



                if i == 3:      
                    x1 = x[0]
                    y1 = y[0]
                    x2 = x[3]
                    y2 = y[3]
                    x3= (x[2]-x[0])*np.cos(-2*beta) + (y[2]-y[0])*np.sin(-2*beta)+x[0]
                    y3 = (y[2]-y[0])*np.cos(-2*beta) - (x[2]-x[0])*np.sin(-2*beta)+y[0]
                    x4= (x[3]-x[0])*np.cos(-2*beta) + (y[3]-y[0])*np.sin(-2*beta)+x[0]
                    y4 = (y[3]-y[0])*np.cos(-2*beta) - (x[3]-x[0])*np.sin(-2*beta)+y[0]
                    #加个标枪
                    x1 = x[3]
                    y1 = y[3]
                    x2= (x[0]-x[3])*np.cos(-2*beta) + (y[0]-y[3])*np.sin(-2*beta)+x[3]
                    y2 = (y[0]-y[3])*np.cos(-2*beta) - (x[0]-x[3])*np.sin(-2*beta)+y[3]
                    x3 = (x[2]-x[3])*np.cos(np.pi) + (y[2]-y[3])*np.sin(np.pi)+x[3]
                    x3 = (a+1-2*a*np.cos(beta))*x3/(a+1) + 2*a*np.cos(beta)*x[3]/(a+1)
                    y3 = (y[2]-y[3])*np.cos(np.pi) - (x[2]-x[3])*np.sin(np.pi)+y[3]
                    y3 = (a+1-2*a*np.cos(beta))*y3/(a+1) + 2*a*np.cos(beta)*y[3]/(a+1)
                    x4= x[0]
                    y4 = y[0]

                    
                    # xlist = [x1,x2,x3,x4,x1]
                    # ylist = [y1,y2,y3,y4,y1]
                    # plt.plot(xlist,ylist)

                    vhandle = []
                    vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
                    vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

                    face_vhandles = []
                    face_vhandles.append(vhandle[0])
                    face_vhandles.append(vhandle[1])
                    face_vhandles.append(vhandle[2])
                    face_vhandles.append(vhandle[3])

                    mesh.add_face(face_vhandles)

                    isextendnow[0] = 1  #这个边扩展完了

                    edgex.append([x1,x2,x3,x4])
                    edgey.append([y1,y2,y3,y4])
                    isextend.append([0,0,0,1])
                    # if mynum < n :
                        # digui(edgex[-1],edgey[-1],isextend[-1],mynum+1,1)#回去递归    




# 初始化一个风筝-----------------------------------------------------------------
x1 = 0
y1 = a*np.cos(beta)
x2 = -a*np.sin(beta)
y2 = 0
x3 = 0
y3 = y1-(1+a)
x4 = a*np.sin(beta)
y4 = 0


xlist = [x1,x2,x3,x4,x1]
ylist = [y1,y2,y3,y4,y1]
plt.plot(xlist,ylist)

mesh = om.TriMesh()


vhandle = []
vhandle.append(mesh.add_vertex(np.array([x1,  y1, 0])))
vhandle.append(mesh.add_vertex(np.array([x2,  y2, 0])))
vhandle.append(mesh.add_vertex(np.array([x3,  y3, 0])))
vhandle.append(mesh.add_vertex(np.array([x4,  y4, 0])))

face_vhandles = []

face_vhandles.append(vhandle[0])
face_vhandles.append(vhandle[1])
face_vhandles.append(vhandle[2])
face_vhandles.append(vhandle[3])

mesh.add_face(face_vhandles)
#------------------------------------------------------------------------
edgex = []#用来存点的x坐标
edgey = []#用来存点的x坐标
isextend = []#存是否扩展了
edgex.append([x1,x2,x3,x4])
edgey.append([y1,y2,y3,y4])
isextend.append([0,0,0,0])
digui(edgex[-1],edgey[-1],isextend[-1],1,0)
print(isextend)
plt.show()
om.write_mesh("./penrose.obj", mesh)


现在的生成效果:
在这里插入图片描述
显然这冲突是一个蛮需要解决的问题。在目前图形下,下一条边要扩展的是风筝还是飞镖?这虽然是随机的,但是有很多情况是不能实现的,比如我剩了一个飞镖的窟窿你要填一个风筝进去,这显然不可嫩。也就是说这应该是由条件限制的,但这个条件有没有一种简洁的表达形式我再思考一下。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值