Advertisement
Guest User

2D.py

a guest
Mar 3rd, 2014
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.34 KB | None | 0 0
  1.  
  2. import random
  3. import numpy as np
  4. import math
  5. try:
  6.     from PIL import Image      # necessary for manipulation with images
  7.     from PIL import ImageFilter
  8.     from PIL import ImageDraw,ImageFont
  9. except:
  10.     print (" Warning: Failed to load Pillow (Imaging) modules!")
  11.     print (" Pillow (fork of PIL) should be available in repositories")
  12.     print (" of your distribution, please install it first.")
  13.     exit()
  14.  
  15.  
  16. length=2**10  #working size
  17. rough_intensity=1.5  #1.5 good
  18. rough_gamma=1.3      #0.85good
  19. highcropprc=2
  20. lowcropprc=5 #% water surface effectively
  21. map_size=384  # final size in widelands
  22. minavg=0.2
  23. maxavg=0.45
  24. seed_intensity=0.15 # 0.66 good, inserting additional randomnes before running diamond square algorithm
  25.  
  26.  
  27.  
  28. px_array=np.zeros(shape=(length,length),dtype=float)
  29. blur_array=np.zeros(shape=(length,length),dtype=float)
  30.  
  31. def new_RGB(bp1,bp2,value,R1,G1,B1,R2,G2,B2):
  32.     ratio=(float(value)-bp1)/(bp2-bp1)
  33.     Rnew=R1*(1-ratio)+ R2*ratio
  34.     Gnew=G1*(1-ratio)+ G2*ratio
  35.     Bnew=B1*(1-ratio)+ B2*ratio
  36.     return Rnew,Gnew,Bnew
  37.  
  38. def wrap(value):
  39.     if value>=length:
  40.         return value-length
  41.     if value<0:
  42.         return value+length
  43.     return value
  44.    
  45.  
  46.  
  47. k=0
  48. listofdef=[0,0.1,0.2,0.8,0.9,1]
  49. while k<10:  #generates 10 fractals (=10 jpg images and txt files with heights)
  50.     print ("Fractal: "+str(k+1))
  51.    
  52.     lowcount=0
  53.     highcount=1
  54.     px_array.fill(-100)    #defaults
  55.     px_array[0 , 0]=random.uniform(0,1)   #at least one value must be given to start fractal generation
  56.    
  57.     #this is an exemption to fractal algorithm but we need to add more randomness/irregularity
  58.     for i in range(8):
  59.         for j in range(8):
  60.             if random.uniform(0,1) > (1- seed_intensity):
  61.                 i_l=int(i/8.0*length)
  62.                 j_l=int(j/8.0*length)
  63.                 px_array[i_l, j_l]=random.choice(listofdef)
  64.  
  65.     sqsize=length
  66.    
  67.     while sqsize >1:
  68.         roughness=math.pow(rough_intensity*float(sqsize)/length,rough_gamma)
  69.         print ("  sqsize: "+str(sqsize)+", roughness: " +str(round(roughness,3)))
  70.         #iterating over line, starting on 0+sqsize/2
  71.  
  72.         pixel_x_pos=0+sqsize/2
  73.        
  74.         while pixel_x_pos<length:
  75.             pixel_y_pos=0+sqsize/2 
  76.             while pixel_y_pos<length:  
  77.                 px1=    px_array[wrap(pixel_x_pos-sqsize/2) , wrap(pixel_y_pos-sqsize/2)]
  78.                 px2=    px_array[wrap(pixel_x_pos-sqsize/2) , wrap(pixel_y_pos+sqsize/2)]
  79.                 px3=    px_array[wrap(pixel_x_pos+sqsize/2) , wrap(pixel_y_pos-sqsize/2)]
  80.                 px4=    px_array[wrap(pixel_x_pos+sqsize/2) , wrap(pixel_y_pos+sqsize/2)]
  81.                    
  82.                 new_value=(px1+px2+px3+px4)/4.0 + random.uniform(-1,1)*roughness
  83.                 if new_value>1:
  84.                     highcount+=1
  85.                 if new_value<0:
  86.                     lowcount+=1        
  87.                 if px1==-100 or px2==-100 or px3==-100 or px4==-100:
  88.                     print ("   touched wrong pixel: "+str(pixel_x_pos)+" x "+str(pixel_y_pos))
  89.                     #exit()
  90.                
  91.                 px_array[pixel_x_pos , pixel_y_pos]=new_value
  92.                 pixel_y_pos=pixel_y_pos+sqsize
  93.             pixel_x_pos=pixel_x_pos+sqsize
  94.        
  95.        
  96.         #iterating once more and populating not calculated pixels
  97.         pixel_x_pos=0
  98.        
  99.         while pixel_x_pos<length:
  100.             pixel_y_pos=0  
  101.             while pixel_y_pos<length:
  102.                 #print (pixel_x_pos,pixel_y_pos)
  103.                 if px_array[pixel_x_pos,pixel_y_pos]>-100:   #never change yet calculated pixel
  104.                     pixel_y_pos=pixel_y_pos+sqsize/2
  105.                     continue
  106.  
  107.                 px1=    px_array[wrap(pixel_x_pos-sqsize/2) , pixel_y_pos]
  108.                 px2=    px_array[wrap(pixel_x_pos+sqsize/2) , pixel_y_pos]
  109.                 px3=    px_array[pixel_x_pos , wrap(pixel_y_pos-sqsize/2)]
  110.                 px4=    px_array[pixel_x_pos , wrap(pixel_y_pos+sqsize/2)] 
  111.                 if px1==-100 or px2==-100 or px3==-100 or px4==-100:
  112.                     print ("   touched wrong pixel: "+str(pixel_x_pos)+" x "+str(pixel_y_pos))
  113.                     #exit()
  114.                    
  115.                 new_value=(px1+px2+px3+px4)/4.0 + random.uniform(-1,1)*roughness
  116.                 if new_value>1:
  117.                     highcount+=1
  118.                 if new_value<0:
  119.                     lowcount+=1
  120.                 #print (str(new_value)+" ( pure avg="+str((px1+px2+px3+px4)/4.0)+")    on pos :"+str(pixel_x_pos)+"  x  "+str(pixel_y_pos))
  121.    
  122.                 px_array[pixel_x_pos , pixel_y_pos]=new_value
  123.                
  124.                 pixel_y_pos=pixel_y_pos+sqsize/2
  125.             pixel_x_pos=pixel_x_pos+sqsize/2
  126.        
  127.         sqsize=sqsize/2
  128.    
  129.    
  130.     newImage = Image.new( 'RGB', (length,length), "black")
  131.    
  132.     #blurring the image
  133.     for i in range(length):
  134.         for j in range(length):
  135.             if px_array[i][j]==-100:
  136.                 print ("unpopulated pixel")
  137.                 exit()
  138.             blur_array[i,j]=(px_array[i,j] + px_array[i,j] + px_array[wrap(i+1),wrap(j)] +
  139.             px_array[wrap(i-1),wrap(j)] + px_array[wrap(i),wrap(j+1)] + px_array[wrap(i),wrap(j-1)])/ 6.0
  140.     #iteration 2
  141.     for i in range(length):
  142.         for j in range(length):
  143.             px_array[i,j]=(blur_array[i,j]  + px_array[i,j] + blur_array[wrap(i+1),wrap(j)] +
  144.             blur_array[wrap(i-1),wrap(j)] +  blur_array[wrap(i),wrap(j+1)] + blur_array[wrap(i),wrap(j-1)])/ 6.0
  145.     #iteration 3
  146.     for i in range(length):
  147.         for j in range(length):
  148.             blur_array[i,j]=(px_array[i,j] + px_array[i,j] + px_array[wrap(i+1),wrap(j)] +
  149.             px_array[wrap(i-1),wrap(j)] + px_array[wrap(i),wrap(j+1)] + px_array[wrap(i),wrap(j-1)])/ 6.0
  150.     #iteration 4
  151.     for i in range(length):
  152.         for j in range(length):
  153.             px_array[i,j]=(blur_array[i,j]  + px_array[i,j] + blur_array[wrap(i+1),wrap(j)] +
  154.             blur_array[wrap(i-1),wrap(j)] +  blur_array[wrap(i),wrap(j+1)] + blur_array[wrap(i),wrap(j-1)])/ 6.0   
  155.    
  156.     #normalizing the image, calculating minvalue and maxvalue
  157.     minvalue=10
  158.     maxvalue=-10
  159.  
  160.     for i in range(length):
  161.         #print(str(i)+" : "+str(px_array[i]))
  162.         for j in range(length):
  163.  
  164.             if  px_array[i][j]<minvalue:
  165.                     minvalue=px_array[i][j]
  166.             elif  px_array[i][j]>maxvalue:
  167.                     maxvalue=px_array[i][j]
  168.  
  169.                
  170.     print ("  Raw fractal values range: "+str(round(minvalue,2)) + " - "+ str(round(maxvalue,2)))  #+", avg: "+str(avgvaluesum/count))
  171.  
  172.     #ordering all pixel values
  173.     allpx=[]
  174.     for i in range(0,length,2):
  175.         for j in range(0,length,2):
  176.             allpx.append(px_array[i][j])
  177.     allpx=sorted(allpx)
  178.  
  179.     lowvalue =allpx[int((lowcropprc/100.0)*len(allpx))]   #this and everything below will be water at level 0
  180.     highvalue=allpx[int(((100-highcropprc)/100.0)*len(allpx))]   #this and all above will be top on level 60
  181.     print ("  Cropping top and bottoms at: "+str(round(lowvalue,2))+ " / "+str(round(highvalue,2)))
  182.  
  183.  
  184.     lowcount=0
  185.     hightcount=0
  186.     avgvaluesum=0
  187.     count=0.0
  188.     #recalculating image
  189.     for i in range(length):
  190.         for j in range(length):
  191.        
  192.             if px_array[i][j]>highvalue:
  193.                 highcount+=1
  194.                 px_array[i][j]=1
  195.             elif px_array[i][j]<lowvalue:
  196.                 lowcount+=1
  197.                 px_array[i][j]=0
  198.             else:
  199.                 #print (str(px_array[i][j])+ " to")
  200.                 px_array[i][j]=(px_array[i][j]-lowvalue)/(highvalue-lowvalue)
  201.                 #print (str(px_array[i][j]))
  202.                 avgvaluesum+=px_array[i,j]  #=math.pow(px_array[i,j],1.3)   #gamma
  203.                 count+=1
  204.  
  205.     avg=float(avgvaluesum)/count
  206.  
  207.     print ("  Average of non-limit pixels: "+str(round(avg,3))+", image split: "+str(lowcount) +" / "+str(count)+" / "+str(highcount))
  208.  
  209.  
  210.     gamma=1
  211.     avgvaluesum=0
  212.     count=0.0
  213.     if avg<minavg:
  214.         gamma=(avg/minavg)**2
  215.         #applying gamma
  216.         for i in range(length):
  217.             for j in range(length):
  218.                 if  px_array[i][j]<1 and  px_array[i][j]>0:
  219.                     px_array[i][j]=pow(px_array[i][j],gamma)
  220.                     avgvaluesum=avgvaluesum+px_array[i][j]
  221.                     count+=1
  222.     elif avg>maxavg:
  223.         gamma=(avg/maxavg)
  224.         #applying gamma
  225.         for i in range(length):
  226.             for j in range(length):
  227.                 if  px_array[i][j]<1 and  px_array[i][j]>0:
  228.                     px_array[i][j]=pow(px_array[i][j],gamma)
  229.                     avgvaluesum=avgvaluesum+px_array[i][j]
  230.                     count+=1                       
  231.     if count>0:
  232.         print ("  applying gamma: "+ str(round(gamma,2))+"(if needed), new average:"+str(round(float(avgvaluesum)/count,2)))
  233.  
  234.  
  235.  
  236.     #verifying the results the image, calculating minvalue and maxvalue
  237.     minvalue=10
  238.     maxvalue=-10
  239.     for i in range(length):
  240.         #print(str(i)+" : "+str(px_array[i]))
  241.         for j in range(length):
  242.             if  px_array[i][j]<minvalue:
  243.                     minvalue=px_array[i][j]
  244.             if  px_array[i][j]>maxvalue:
  245.                     maxvalue=px_array[i][j]            
  246.                
  247.     print ("  Modified image value range: "+str(minvalue) + " - "+ str(maxvalue))
  248.    
  249.  
  250.  
  251.  
  252.     #output as jpg image
  253.     P1R=0   #grass
  254.     P1G=70
  255.     P1B=0
  256.     P2R=61  #light green
  257.     P2G=114
  258.     P2B=61
  259.     P3R=112   #light brown
  260.     P3G=112
  261.     P3B=76
  262.     P4R=56 #dark brown
  263.     P4G=55
  264.     P4B=5
  265.     P5R=210
  266.     P5G=209
  267.     P5B=203
  268.    
  269.     for i in range(length):
  270.         #print(str(i)+" : "+str(px_array[i]))
  271.         for j in range(length):
  272.             if px_array[i][j]==-100:
  273.                 print ("unpopulated pixel")
  274.                 exit()
  275.             value=px_array[i][j]*255
  276.             if value<=0:
  277.                 finalR=0
  278.                 finalG=115
  279.                 finalB=232 
  280.             elif value<60:
  281.                 finalR,finalG,finalB = new_RGB(0,60,value,P1R,P1G,P1B,P2R,P2G,P2B)
  282.             elif value<130:
  283.                 finalR,finalG,finalB = new_RGB(60,130,value,P2R,P2G,P2B,P3R,P3G,P3B)
  284.             elif value<215:
  285.                 finalR,finalG,finalB = new_RGB(130,215,value,P3R,P3G,P3B,P4R,P4G,P4B)
  286.             else:
  287.                 finalR,finalG,finalB = new_RGB(215,255,value,P5R,P5G,P5B,255,255,255)
  288.        
  289.             newImage.putpixel((i,j),(int(finalR),int(finalG),int(finalB)))
  290.    
  291.     newname="Terrain_"+str(k+1)+".jpg"
  292.     newImage.save(newname,quality=98)
  293.    
  294.    
  295.     #output to file
  296.     filename="import_coordinates_"+str(k+1)+".txt"
  297.     f = open(filename, 'w')
  298.     for i in range(map_size):
  299.         x=round(float(i)/map_size*length)
  300.         #print (" calculating : " +str(i) + "->"+str(x))
  301.         for j in range(map_size):
  302.             offset=0
  303.             if j%2==1:
  304.                 offset=0.5
  305.             y=round(float(j+offset)/map_size*length)
  306.             if px_array[x][y]==0:
  307.                 value=0
  308.             else:
  309.                 value=min ((px_array[x][y]*60.0)+1 , 60)
  310.                 value=max(value,0)
  311.                 value=int(value)
  312.             f.write(str(i)+" "+str(j)+" "+str(value)+'\n')
  313.         f.write (' \n')
  314.     f.close
  315.    
  316.     k=k+1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement