[关闭]
@ibilis 2017-01-08T12:29:33.000000Z 字数 3802 阅读 598

期末 代码

计算物理


1.Mandelbrot集合

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import pylab as pl
  4. import time
  5. from matplotlib import cm
  6. def iter_point(c):
  7. z = c
  8. for i in xrange(1, 100): # 最多迭代100次
  9. if abs(z)>2: break # 半径大于2则认为逃逸
  10. z = z*z+c
  11. return i # 返回迭代次数
  12. def draw_mandelbrot(cx, cy, d):
  13. """
  14. 绘制点(cx, cy)附近正负d的范围的Mandelbrot
  15. """
  16. x0, x1, y0, y1 = cx-d, cx+d, cy-d, cy+d
  17. y, x = np.ogrid[y0:y1:200j, x0:x1:200j]
  18. c = x + y*1j
  19. start = time.clock()
  20. mandelbrot = np.frompyfunc(iter_point,1,1)(c).astype(np.float)
  21. print "time=",time.clock() - start
  22. pl.imshow(mandelbrot, cmap=cm.Blues_r, extent=[x0,x1,y0,y1])
  23. pl.gca().set_axis_off()
  24. x,y = 0.27322626, 0.595153338
  25. pl.subplot(231)
  26. draw_mandelbrot(-0.5,0,1.5)
  27. for i in range(2,7):
  28. pl.subplot(230+i)
  29. draw_mandelbrot(x, y, 0.2**(i-1))
  30. pl.subplots_adjust(0.2, 0, 0.98, 1, 0.2, 0)
  31. pl.show()

2.分形蕨类植物

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import matplotlib.pyplot as pl
  4. import time
  5. # 蕨类植物叶子的迭代函数和其概率值
  6. eq1 = np.array([[0,0,0],[0,0.16,0]])
  7. p1 = 0.01
  8. eq2 = np.array([[0.2,-0.26,0],[0.23,0.22,1.6]])
  9. p2 = 0.07
  10. eq3 = np.array([[-0.05, 0.28, 0],[0.26,0.24,0.44]])
  11. p3 = 0.07
  12. eq4 = np.array([[0.85, 0.04, 0],[-0.04, 0.85, 1.6]])
  13. p4 = 0.85
  14. def ifs(p, eq, init, n):
  15. """
  16. 进行函数迭代
  17. p: 每个函数的选择概率列表
  18. eq: 迭代函数列表
  19. init: 迭代初始点
  20. n: 迭代次数
  21. 返回值: 每次迭代所得的X坐标数组, Y坐标数组, 计算所用的函数下标
  22. """
  23. # 迭代向量的初始化
  24. pos = np.ones(3, dtype=np.float)
  25. pos[:2] = init
  26. # 通过函数概率,计算函数的选择序列
  27. p = np.add.accumulate(p)
  28. rands = np.random.rand(n)
  29. select = np.ones(n, dtype=np.int)*(n-1)
  30. for i, x in enumerate(p[::-1]):
  31. select[rands<x] = len(p)-i-1
  32. # 结果的初始化
  33. result = np.zeros((n,2), dtype=np.float)
  34. c = np.zeros(n, dtype=np.float)
  35. for i in xrange(n):
  36. eqidx = select[i] # 所选的函数下标
  37. tmp = np.dot(eq[eqidx], pos) # 进行迭代
  38. pos[:2] = tmp # 更新迭代向量
  39. # 保存结果
  40. result[i] = tmp
  41. c[i] = eqidx
  42. return result[:,0], result[:, 1], c
  43. start = time.clock()
  44. x, y, c = ifs([p1,p2,p3,p4],[eq1,eq2,eq3,eq4], [0,0], 100000)
  45. print time.clock() - start
  46. pl.figure(figsize=(6,6))
  47. pl.subplot(121)
  48. pl.scatter(x, y, s=1, c="g", marker="s", linewidths=0)
  49. pl.axis("equal")
  50. pl.axis("off")
  51. pl.subplot(122)
  52. pl.scatter(x, y, s=2,c = c, marker="s", linewidths=0)
  53. pl.axis("equal")
  54. pl.axis("off")
  55. pl.subplots_adjust(left=0,right=1,bottom=0,top=1,wspace=0,hspace=0)
  56. pl.gcf().patch.set_facecolor("white")
  57. pl.show()

3.L-System分形

  1. # -*- coding: utf-8 -*-
  2. #L-System(Lindenmayer system)是一种用字符串替代产生分形图形的算法
  3. from math import sin, cos, pi
  4. import matplotlib.pyplot as pl
  5. from matplotlib import collections
  6. class L_System(object):
  7. def __init__(self, rule):
  8. info = rule['S']
  9. for i in range(rule['iter']):
  10. ninfo = []
  11. for c in info:
  12. if c in rule:
  13. ninfo.append(rule[c])
  14. else:
  15. ninfo.append(c)
  16. info = "".join(ninfo)
  17. self.rule = rule
  18. self.info = info
  19. def get_lines(self):
  20. d = self.rule['direct']
  21. a = self.rule['angle']
  22. p = (0.0, 0.0)
  23. l = 1.0
  24. lines = []
  25. stack = []
  26. for c in self.info:
  27. if c in "Ff":
  28. r = d * pi / 180
  29. t = p[0] + l*cos(r), p[1] + l*sin(r)
  30. lines.append(((p[0], p[1]), (t[0], t[1])))
  31. p = t
  32. elif c == "+":
  33. d += a
  34. elif c == "-":
  35. d -= a
  36. elif c == "[":
  37. stack.append((p,d))
  38. elif c == "]":
  39. p, d = stack[-1]
  40. del stack[-1]
  41. return lines
  42. rules = [
  43. {
  44. "X":"F-[[X]+X]+F[+FX]-X", "F":"FF", "S":"X",
  45. "direct":-45,
  46. "angle":25,
  47. "iter":6,
  48. "title":"Plant"
  49. },
  50. ]
  51. def draw(ax, rule, iter=None):
  52. if iter!=None:
  53. rule["iter"] = iter
  54. lines = L_System(rule).get_lines()
  55. linecollections = collections.LineCollection(lines)
  56. ax.add_collection(linecollections, autolim=True)
  57. ax.axis("equal")
  58. ax.set_axis_off()
  59. ax.set_xlim(ax.dataLim.xmin, ax.dataLim.xmax,'g')
  60. ax.invert_yaxis()
  61. fig = pl.figure(figsize=(7,4.5))
  62. fig.patch.set_facecolor("w")
  63. for i in xrange(1):
  64. ax = fig.add_subplot(231+i)
  65. draw(ax, rules[0],)
  66. fig.subplots_adjust(left=0,right=2,bottom=0,top=2,wspace=0,hspace=0)
  67. pl.show()

4.分形山脉

  1. import numpy as np
  2. import pylab as py
  3. from numpy.random import normal
  4. from mayavi import mlab
  5. def hill2d(n,d):
  6. size=2**n+1
  7. scale=1.0
  8. a=np.zeros((size,size))
  9. for i in xrange(n,0,-1):
  10. s=2**(i-1)
  11. s2=s*2
  12. tmp=a[::s2,::s2]
  13. tmp1=(tmp[1:,:]+tmp[:-1,:]*0.5)
  14. tmp2=(tmp[:,1:]+tmp[:,:-1]*0.5)
  15. tmp3=(tmp1[:,1:]+tmp1[:,:-1]*0.5)
  16. a[s::s2,::s2]=tmp1+normal(0,scale,tmp1.shape)
  17. a[::s2,s::s2]=tmp2+normal(0,scale,tmp2.shape)
  18. a[s::s2,s::s2]=tmp3+normal(0,scale,tmp3.shape)
  19. scale *=d
  20. return a
  21. if __name__=='__main__':
  22. from mayavi import mlab
  23. from scipy.ndimage.filters import convolve
  24. a=hill2d(8,0.5)
  25. a/=np.ptp(a)/(0.5*2**8)
  26. a=convolve(a,np.ones((3,3))/9)
  27. mlab.surf(a)
  28. mlab.show()
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注