2011-04-03 15 views
8

एक सेलुलर ऑटोमाटा प्रोजेक्ट के लिए मैं काम कर रहा हूं, मुझे अलग-अलग एल्गोरिदम और तकनीकों का उपयोग करके यादृच्छिक रूप से दो आयामी बूलियन सरणी उत्पन्न करने की आवश्यकता है। फिलहाल मेरे पास एप्लिकेशन में केवल एक प्रकार का यादृच्छिकरण है - सरणी में प्रत्येक सेल के माध्यम से लूपिंग और यादृच्छिक डबल वैरिएबल उत्पन्न करना, फिर यदि यादृच्छिक संख्या 0.5 से अधिक है तो मैंने उस सेल को सत्य पर सेट किया है, अगर यह सेट नहीं हो जाता है झूठीजावा में पर्लिन शोर

मैं इन बूलियन मैट्रिस को अधिक दिलचस्प एल्गोरिदम का उपयोग करके देखना चाहता हूं जैसे कि पर्लिन नोएस या ऐसा कुछ। शोर जनरेटर जो इलाके की पीढ़ी में उपयोग किए जाते हैं या ऐसा कुछ अच्छा हो सकता है यदि आप पर्लिन शोर के अलावा किसी अन्य के बारे में जानते हैं (Minecraft की विश्व पीढ़ी ने मुझे यह विचार दिया)।

समस्या सिर्फ मुझे पता नहीं कहाँ शुरू करने के लिए है (किसी भी विचार?) :)

उत्तर

9

पहली बात मैं के बारे में सोचा एक यादृच्छिक विस्थापन भग्न था। यह इलाके उत्पन्न करने के लिए भी प्रयोग किया जाता है और पर्लिन शोर से आसान है।

package so; 

import java.util.Random; 

public class Noise { 
    /** Source of entropy */ 
    private Random rand_; 

    /** Amount of roughness */ 
    float roughness_; 

    /** Plasma fractal grid */ 
    private float[][] grid_; 


    /** Generate a noise source based upon the midpoint displacement fractal. 
    * 
    * @param rand The random number generator 
    * @param roughness a roughness parameter 
    * @param width the width of the grid 
    * @param height the height of the grid 
    */ 
    public Noise(Random rand, float roughness, int width, int height) { 
     roughness_ = roughness/width; 
     grid_ = new float[width][height]; 
     rand_ = (rand == null) ? new Random() : rand; 
    } 


    public void initialise() { 
     int xh = grid_.length - 1; 
     int yh = grid_[0].length - 1; 

     // set the corner points 
     grid_[0][0] = rand_.nextFloat() - 0.5f; 
     grid_[0][yh] = rand_.nextFloat() - 0.5f; 
     grid_[xh][0] = rand_.nextFloat() - 0.5f; 
     grid_[xh][yh] = rand_.nextFloat() - 0.5f; 

     // generate the fractal 
     generate(0, 0, xh, yh); 
    } 


    // Add a suitable amount of random displacement to a point 
    private float roughen(float v, int l, int h) { 
     return v + roughness_ * (float) (rand_.nextGaussian() * (h - l)); 
    } 


    // generate the fractal 
    private void generate(int xl, int yl, int xh, int yh) { 
     int xm = (xl + xh)/2; 
     int ym = (yl + yh)/2; 
     if ((xl == xm) && (yl == ym)) return; 

     grid_[xm][yl] = 0.5f * (grid_[xl][yl] + grid_[xh][yl]); 
     grid_[xm][yh] = 0.5f * (grid_[xl][yh] + grid_[xh][yh]); 
     grid_[xl][ym] = 0.5f * (grid_[xl][yl] + grid_[xl][yh]); 
     grid_[xh][ym] = 0.5f * (grid_[xh][yl] + grid_[xh][yh]); 

     float v = roughen(0.5f * (grid_[xm][yl] + grid_[xm][yh]), xl + yl, yh 
       + xh); 
     grid_[xm][ym] = v; 
     grid_[xm][yl] = roughen(grid_[xm][yl], xl, xh); 
     grid_[xm][yh] = roughen(grid_[xm][yh], xl, xh); 
     grid_[xl][ym] = roughen(grid_[xl][ym], yl, yh); 
     grid_[xh][ym] = roughen(grid_[xh][ym], yl, yh); 

     generate(xl, yl, xm, ym); 
     generate(xm, yl, xh, ym); 
     generate(xl, ym, xm, yh); 
     generate(xm, ym, xh, yh); 
    } 


    /** 
    * Dump out as a CSV 
    */ 
    public void printAsCSV() { 
     for(int i = 0;i < grid_.length;i++) { 
      for(int j = 0;j < grid_[0].length;j++) { 
       System.out.print(grid_[i][j]); 
       System.out.print(","); 
      } 
      System.out.println(); 
     } 
    } 


    /** 
    * Convert to a Boolean array 
    * @return the boolean array 
    */ 
    public boolean[][] toBooleans() { 
     int w = grid_.length; 
     int h = grid_[0].length; 
     boolean[][] ret = new boolean[w][h]; 
     for(int i = 0;i < w;i++) { 
      for(int j = 0;j < h;j++) { 
       ret[i][j] = grid_[i][j] < 0; 
      } 
     } 
     return ret; 
    } 


    /** For testing */ 
    public static void main(String[] args) { 
     Noise n = new Noise(null, 1.0f, 250, 250); 
     n.initialise(); 
     n.printAsCSV(); 
    } 
} 

random displacement fractal plot 1 random displacement fractal plot 2 random displacement fractal plot 3

+0

मैंने आपके स्रोत को शोर की साजिश का उत्पादन करने के लिए बदल दिया, नीले रंग के निम्नतम और पीले उच्चतम मूल्यों के साथ। छवि पर अलग-अलग रेखाएं प्रतीत होती हैं, जो कि 'मध्य बिंदु' पर सबसे अधिक ध्यान देने योग्य हैं, लेकिन कुछ हद तक, प्रत्येक 'बच्चे' मध्यबिंदु। क्या उन असंतुलन को कम करने या उन्मूलन करने का कोई तरीका है? यदि कोई दिलचस्पी लेता है, तो मैं परिवर्तित स्रोत जोड़ सकता हूं। –

+2

यह फ्रैक्टल कोड के लिए आसान है लेकिन इन लाइनों का उत्पादन करता है। इस पर एक सुधार है हीरा वर्ग फ्रैक्टल के रूप में जाना जाता है जिसे इन कलाकृतियों को कम करना है। –

+0

बीटीडब्ल्यू मुझे लगता है कि मेरे कार्यान्वयन में भी एक समस्या है। कोड प्रत्येक तरफ midpoints की ऊंचाई दो बार सेट करता है। यह असंतोष के लिए बनाता है। यदि ग्रिड को फ्लोट.NAN में प्रारंभ किया गया है और प्रत्येक बिंदु केवल इसके लिए परीक्षण करके सेट किया गया है, तो मुझे लगता है कि आउटपुट में सुधार होगा। –

4

मैं अपने पुस्तकालय कोड में कुछ पर्लिन शोर कार्यान्वयन और कुछ अन्य शोर पीढ़ी कार्यों:

http://code.google.com/p/mikeralib/source/browse/#svn%2Ftrunk%2FMikera%2Fsrc%2Fmain%2Fjava%2Fmikera%2Fmath

का पता लगाने के लिए स्वतंत्र महसूस/उपयोग (कोड जे 3 डी कोड के आधार पर ओपन सोर्स जीपीएल है)।

+0

सोच रहा है कि मुझे आपके पेर्लिन कार्यों से नकारात्मक या सकारात्मक 0 फ़्लोटिंग पॉइंट नंबरों के अलावा कुछ भी नहीं मिल रहा है; 'पर्लिननोइस पेरिन = नया पर्लिननोइस (40 9 623546); (फ्लोट x = 0; x <100; x ++) { (फ्लोट वाई = 0; वाई <100; वाई ++) { System.out.println (perlin।noise1 (y) * 100000); } } ' –

+0

@ टिमोथीग्रोट इसे आज़माएं, यह मेरे लिए काम करता है: डबल ग्रिड [] [] = नई डबल [चौड़ाई] [ऊंचाई]; (int y = 0; y <ऊंचाई; y ++) { (int x = 0; x

संबंधित मुद्दे