import matplotlib.pyplot as plt
import numpy as np
fengye=[(0,0,0,0.5,0,0,0.05),
        (0.12,-0.82,0.42,0.42,0,0.2,0.4),
        (0.12,0.82,-0.42,0.42,0,0.2,0.4),
        (0.1,0,0,0.1,0,0.2,0.15)]
#点序列集生成函数,第1个参数IFS_code为IFS码,第2个参数n为点数
def create_dots(IFS_code,n):
    #设置初始点位置
    x=0
    y=0
    #初始化点序列集为嵌套空列表,一个仿射变换对应dots的一个元素
    dots=[[] for i in range(len(IFS_code))]
    #获取IFS_code中每个仿射变换的概率,最后一个IFS_code元素是概率
    P=[c[-1] for c in IFS_code]
    #生成点序列集
    for dot in range(n):
        r=np.random.rand()#生成(0,1)之间的一个随机浮点数
        #依照随机数r,选择仿射变换
        p0=0
        for i,p in enumerate(P):
            p1=p0+p
            if r>p0 and r<=p1:
                k=i
                break
            else:
                p0=p1
        #获取6个仿射变换系数
        a=IFS_code[k][0]
        b=IFS_code[k][1]
        c=IFS_code[k][2]
        d=IFS_code[k][3]
        e=IFS_code[k][4]
        f=IFS_code[k][5]
        #计算仿射变换后的坐标
        u=a*x+b*y+e
        y=c*x+d*y+f
        x=u
        #将仿射变换后的点加入点序列集dots的对应元素中
        dots[k].append((x,y))
    return  dots
#开始主程序
if __name__=='__main__':
    #配置默认参数,支持中文显示,字体为‘宋体’
    plt.rcParams['font.sans-serif']=['SimSun']
    plt.rcParams['axes.unicode_minus']=False#用来正常显示负号
    #设置x轴,y轴的单位长度相等
    plt.axis('equal')
    #设置标题
    plt.title('拼 贴 图')
    #设置网格
    plt.grid(color='0.1',linestyle='--',linewidth=0.5)
    #设置x轴,y轴标题
    plt.xlabel('X轴')
    plt.ylabel('Y轴')
    #设置x轴,y轴标签位置
    plt.xticks(np.arange(-1,1,0.1),rotation=20)#调用numpy的arange函数生成刻度位置的数组
    plt.yticks(np.arange(0,1,0.1))
    #依据IFS_code生成点序列集dots
    dots=create_dots(fengye,5000)
    #依据点序列集,绘制图形
    for i in range(len(dots)):
        X=[d[0] for d in dots[i]]
        Y=[d[1] for d in dots[i]]
        plt.scatter(X,Y,s=3,label='仿射变换'+str(i+1))
    #显示图例
    plt.legend(loc='lower right')
    #保存图形到文件
    plt.savefig('E:\\1.png')
    #在屏幕上显示图形
    plt.show()
