mapgen.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # http://stackoverflow.com/questions/8997099/algorithm-to-generate-random-2d-polygon
  4. import os, glob, errno
  5. import math, random
  6. from PIL import Image, ImageDraw
  7. import svgwrite
  8. def generatePolygon( ctrX, ctrY, aveRadius, irregularity, spikeyness, numVerts ) :
  9. '''Start with the centre of the polygon at ctrX, ctrY,
  10. then creates the polygon by sampling points on a circle around the centre.
  11. Randon noise is added by varying the angular spacing between sequential points,
  12. and by varying the radial distance of each point from the centre.
  13. Params:
  14. ctrX, ctrY - coordinates of the "centre" of the polygon
  15. aveRadius - in px, the average radius of this polygon, this roughly controls how large the polygon is, really only useful for order of magnitude.
  16. irregularity - [0,1] indicating how much variance there is in the angular spacing of vertices. [0,1] will map to [0, 2pi/numberOfVerts]
  17. spikeyness - [0,1] indicating how much variance there is in each vertex from the circle of radius aveRadius. [0,1] will map to [0, aveRadius]
  18. numVerts - self-explanatory
  19. Returns a list of vertices, in CCW order.
  20. '''
  21. irregularity = clip( irregularity, 0,1 ) * 2*math.pi / numVerts
  22. spikeyness = clip( spikeyness, 0,1 ) * aveRadius
  23. # generate n angle steps
  24. angleSteps = []
  25. lower = (2*math.pi / numVerts) - irregularity
  26. upper = (2*math.pi / numVerts) + irregularity
  27. sum = 0
  28. for i in range(numVerts) :
  29. tmp = random.uniform(lower, upper)
  30. angleSteps.append( tmp )
  31. sum = sum + tmp
  32. # normalize the steps so that point 0 and point n+1 are the same
  33. k = sum / (2*math.pi)
  34. for i in range(numVerts) :
  35. angleSteps[i] = angleSteps[i] / k
  36. # now generate the points
  37. points = []
  38. angle = random.uniform(0, 2*math.pi)
  39. for i in range(numVerts) :
  40. r_i = clip( random.gauss(aveRadius, spikeyness), 0, 2*aveRadius )
  41. x = ctrX + r_i*math.cos(angle)
  42. y = ctrY + r_i*math.sin(angle)
  43. points.append( (int(x),int(y)) )
  44. angle = angle + angleSteps[i]
  45. return points
  46. def clip(x, min, max) :
  47. if( min > max ) : return x
  48. elif( x < min ) : return min
  49. elif( x > max ) : return max
  50. else : return x
  51. # create maps export folder
  52. directory = "maps"
  53. try:
  54. os.makedirs(directory)
  55. except OSError as exception:
  56. if exception.errno != errno.EEXIST:
  57. raise
  58. # remove old image
  59. # os.chdir(directory)
  60. # files=glob.glob('*')
  61. # for filename in files:
  62. # os.unlink(filename)
  63. for i in range(0, 1):
  64. verts = generatePolygon( ctrX=500, ctrY=500, aveRadius=300, irregularity=1, spikeyness=0.15, numVerts=13 )
  65. index = str(i) if i > 9 else '0'+str(i)
  66. # ______ ________
  67. # / ___/ | / / ____/
  68. # \__ \| | / / / __
  69. # ___/ /| |/ / /_/ /
  70. # /____/ |___/\____/
  71. svg = svgwrite.Drawing(filename = directory+"/map"+index+".svg",size = ("1000px", "1000px"))
  72. print(len(verts))
  73. for v in range(0, len(verts)):
  74. print('---- '+str(v)+' ----')
  75. # p1 = verts[v]
  76. # p2 = verts[0] if v >= len(verts) else verts[v+1];
  77. # print(p1)
  78. # print(p2)
  79. # svg.add(svg.line(p1, p2))
  80. svg.save()
  81. # __ _ __
  82. # / /_ (_) /_____ ___ ____ _____
  83. # / __ \/ / __/ __ `__ \/ __ `/ __ \
  84. # / /_/ / / /_/ / / / / / /_/ / /_/ /
  85. # /_.___/_/\__/_/ /_/ /_/\__,_/ .___/
  86. # /_/
  87. # black = (0,0,0)
  88. # white=(255,255,255)
  89. # im = Image.new('RGB', (1000, 1000), white)
  90. # imPxAccess = im.load()
  91. # draw = ImageDraw.Draw(im)
  92. # tupVerts = list(map(tuple,verts))
  93. #
  94. # # either use .polygon(), if you want to fill the area with a solid colour
  95. # # draw.polygon( tupVerts, outline=black,fill=white )
  96. #
  97. # # or .line() if you want to control the line thickness, or use both methods together!
  98. # draw.line( tupVerts+[tupVerts[0]], width=1, fill=black )
  99. #
  100. # # im.show()
  101. # im.save(directory+'/map-'+str(index)+'.bmp')
  102. # # now you can save the image (im), or do whatever else you want with it.