यादृच्छिक काले और सफ़ेद जंगल ड्रा करें


66

आपका कार्य प्रोग्राम लिखना है जो 800x600 ब्लैक-एंड-व्हाइट छवि को आकर्षित करेगा जिसमें कुछ जंगल जैसा दिखता है।

इस तरह (यह dithered फोटो है):

नियम

  • आपको किसी भी मौजूदा छवियों का उपयोग करने के लिए अस्वीकृत कर दिया गया है - आपको शुद्ध रूप से एल्गोरिथम छवि उत्पन्न करनी चाहिए
  • केवल 2 रंगों का उपयोग करें - काला और सफेद (कोई ग्रेस्केल नहीं)
  • हर बार प्रोग्राम रन इमेज में हर बार नया - रैंडम होना चाहिए
  • एक पेड़ जंगल नहीं है (मान लीजिए 5 पेड़ मिनमम हैं)
  • पेड़ों / जंगलों को खींचने के लिए विशेष पुस्तकालयों को बंद कर दिया गया है
  • अधिकांश मतों से उत्तर जीतता है

9
यह प्रश्न ऑफ़-टॉपिक प्रतीत होता है क्योंकि यह प्रोग्रामिंग प्रतियोगिता के बजाय एक कला प्रतियोगिता है।
प्रोग्रामफॉक्स

19
@ProgramFOX प्रोग्रामिंग कला नहीं है? :)
सोमनीयम

15
मैं, एक के लिए, इस चुनौती के लिए कुछ प्रविष्टियाँ देखना चाहता हूँ, और निराश हूँ कि इसे रोक दिया गया।
ब्रैडेन बेस्ट

3
मुझे यह चुनौती पसंद है। जवाब जो इस की भावना में नहीं हैं, उतने ऊपर नहीं उठेंगे, तो समस्या क्या है?
cjfaure

3
@cjfaure विभिन्न प्रयोजनों के लिए, उदाहरण के लिए खेलों के लिए मॉडल और चित्र बनाने के लिए।
सोमनीयम

जवाबों:


98

C: 3863 1144 1023 999 942 927

मूल समाधान प्रति रन 2 पीएनएम फ़ाइलों को बचाता है (जीथिंग के साथ एक, डिथिंग करने से पहले)। क्योंकि पहले कुछ पंक्तियों के लिए डिटरिंग सुंदर नहीं था, उत्पादन के दौरान ज़रूरत से ज़्यादा लाइनें और फसल को प्रस्तुत करने के लिए एक हैक है।

गोल्फ के घोल में एक सरल चित्रण होता है और केवल बिंदीदार छवि को सहेजता है। (कोई चेतावनी gcc -std = c11--antic -Wall -Wextra के साथ)

3 मूल प्रोग्राम रन और गोल्फ संस्करण के एक रन (अंतिम छवि) से उदाहरण चित्र:

उदाहरण 1 उदाहरण 2 उदाहरण 3 उदाहरण 4

गोल्फ संस्करण

  #include <math.h>
  #include <time.h>
  #include <stdlib.h>
  #include <stdio.h>
  #define D float
  #define R rand()/RAND_MAX
  #define Z(a,b,c) if(10.*R>a)T(h,s,j+b+c*R,g);
  #define U a[y][x]
  #define V e[y+1][x
  #define F(x) for(i=0;i<x;++i)
  int i,x,y,W=800,H=600;unsigned char a[600][800],c;D e[601][802],r,b,k,l,m,n,f,w,
  d,q=.01;void T(D h,D s,D j,D g){r=b=0;do{j+=.04*R-.02;h+=sin(j)*q;s+=cos(j)*q;b
  +=q;g+=q;f=525/d;r=.25-g/44;m=w*f+s*f+W/2;n=2*f-h*f+H/2;f*=r;for(y=n-f-2;y<n+f+2
  ;++y)if(y>=0&&y<H)for(x=m-f-2;x<m+f+2;++x)if(x>=0&&x<W)if(k=m-x,l=n-y,f>sqrt(k*k
  +l*l))if(U>d*3)U=d*3;}while(b<10*r+12*r*R&&r>q);if(r>q){Z(2,.26,.35)Z(2,-.26,-
  .35)Z(7,-.05,.1)}}int main(){FILE* o=fopen("i","wb");srand(time(0));F(W*H){y=i/W
  ;a[y][i%W]=(y<313)?255:6e3/(2*y-H);}F(200)w=1e2*R-60,d=80.*R+5,T(0,0,1.58,0);F(W
  *H){x=i%W;y=i/W;k=U+e[y][x+1];U=-(k>0);l=(k-U)*.1;e[y][x+2]+=l*4;V]+=l*2;V+1]+=l
  *3;V+2]+=l;}fprintf(o,"P5 800 600 255 ");fwrite(a,1,W*H,o);}

मूल संस्करण

  #include <math.h>
  #include <stdio.h>
  #include <stdlib.h>

  #define W 800
  #define H 600
  #define SPEED 0.01
  #define HEIGHT 11.0

  #define R(m) ((double)(m) * rand() / RAND_MAX)
  #define RAD(deg) ((deg) / 180.0 * M_PI)
  #define LIMIT(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))

  void shade(void);
  void growTree(double dist, double side, double h, double s, double alpha, double grown);
  void plot(double dist, double side, double h, double s, double alpha, double diam);
  void dither(void);
  void writeImg(int dither);

  unsigned char img[H+10][W];
  double err[H+10+2][W+4];
  long tim;

  int main(void)
  {
     int i;
     tim = time(0);
     srand(tim);
     shade();
     for(i = 0; i < 200; ++i)
     {
        growTree(5 + R(75), -60 + R(120), 0.0, 0.0, RAD(90), 0.0);
     }
     writeImg(0);
     dither();
     writeImg(1);
  }

  void shade(void)
  {
     int y;
     for(y = -10; y < H; ++y)
     {
        double dist = H * 3.5 / (2 * y - H);
        unsigned char color = dist / 80 * 255;
        if(y <= H / 2 || dist > 80) color = 255;
        memset(img[y+10], color, W);
     }
  }

  void growTree(double dist, double side, double h, double s, double alpha, double grown)
  {
     double diam, branchLength = 0.0;

     do
     {
        alpha += R(RAD(3)) - RAD(1.5);
        h += sin(alpha) * SPEED;
        s += cos(alpha) * SPEED;
        branchLength += SPEED;
        grown += SPEED;
        diam = (1.0 - grown / HEIGHT) * 0.5;
        plot(dist, side, h, s, alpha, diam);
     } while(branchLength < 5 * diam + R(6 * diam) && diam > 0.02);

     if(diam > 0.02)
     {
        int br = 0;

        if(R(10) > 2) br++,growTree(dist, side, h, s, alpha + RAD(15) + R(RAD(20)), grown);
        if(R(10) > 2) br++,growTree(dist, side, h, s, alpha - RAD(15) - R(RAD(20)), grown);
        if(R(10) < 2 || br == 0) growTree(dist, side, h, s, alpha - RAD(2.5) + R(RAD(5)), grown);
     }
  }

  void plot(double dist, double side, double h, double s, double alpha, double diam)
  {
     int x, y;
     double scale = H / 4.0 * 3.5 / dist;
     double x0 = side * scale + s * scale + W / 2.0;
     double y0 = H / 2.0 + 2.0 * scale - h * scale;
     diam *= scale;
     h *= scale;
     s *= scale;
     for(y = y0 - diam / 2 - 2; y < y0 + diam / 2 + 2; ++y)
     {
        if(y < -10 || y >= H) continue;
        for(x = x0 - diam / 2 - 2; x < x0 + diam / 2 + 2; ++x)
        {
           double dx, dy, d;
           if(x < 0 || x >= W) continue;
           dx = x0 - x;
           dy = y0 - y;
           d = diam / 2 - sqrt(dx * dx + dy * dy) + 0.5;
           if(d > 0)
           {
              unsigned char color = dist / 80 * 255;
              if(img[y+10][x] > color) img[y+10][x] = color;
           }
        }
     }
  }

  void dither(void)
  {
     int x0, x, y;
     for(y = -10; y < H; ++y)
     {
        for(x0 = 0; x0 < W; ++x0)
        {
           double error, oldpixel;
           unsigned char newpixel;
           if(y%2) x = W - 1 - x0;
           else x = x0;
           oldpixel = img[y+10][x] + err[y+10][x+2];
           newpixel = oldpixel > 127 ? 255 : 0;
           img[y+10][x] = newpixel;
           error = oldpixel - newpixel;
           err[y+10  ][x+1+2*(1-y%2)] += error * 7 / 48;
           err[y+10  ][x+4*(1-y%2)] += error * 5 / 48;
           err[y+10+1][x  ] += error * 3 / 48;
           err[y+10+1][x+1] += error * 5 / 48;
           err[y+10+1][x+2] += error * 7 / 48;
           err[y+10+1][x+3] += error * 5 / 48;
           err[y+10+1][x+4] += error * 3 / 48;
           err[y+10+2][x  ] += error * 1 / 48;
           err[y+10+2][x+1] += error * 3 / 48;
           err[y+10+2][x+2] += error * 5 / 48;
           err[y+10+2][x+3] += error * 3 / 48;
           err[y+10+2][x+4] += error * 1 / 48;
        }
     }
  }

  void writeImg(int dither)
  {
     FILE* fp;
     char buffer[32];
     sprintf(buffer, "%ld%s.pnm", tim, dither ? "" : "g");
     fp = fopen(buffer, "wb");
     fprintf(fp, "P5\n%d %d\n255\n", W, H);
     fwrite(&img[10][0], 1, W * H, fp);
     fclose(fp);
  }

3
+1। अच्छी फोटो। वैसे भी, यह लोकप्रियता-प्रतियोगिता है, कोड-गोल्फ नहीं। तो, गोल्फ की कोई जरूरत नहीं है। :)
०41:

2
अच्छा लग रहा है, मेरे पास एक समान विचार था लेकिन बहुत आलसी था =) मुझे लगता है कि आप शाखाओं की पुनरावृत्ति गहराई को यादृच्छिक बनाने की कोशिश कर सकते हैं, मुझे लगता है कि यह और भी स्वाभाविक लगेगा।
15

3
मुझे पता है कि मैं इसे गोल्फ की जरूरत नहीं है, लेकिन यह मेरे लिए सबसे मजेदार हिस्सा है!
मैनुअल कास्टेन

2
यह शानदार है।
क्वेंटिन

12
इसके अलावा, मैंने सीपिया टोन में एक अनडिथर्ड संस्करण डाला - भव्य! यहां देखें: i.imgur.com/lCrJCp7.jpg
DreamWarrior

42

जावा जंगल

(954 गोल्फ

गहरे, घुमा देने वाले गहरे भाग से भरा, यह एक जंगल है जो आसानी से नहीं दिखता है।

यहाँ छवि विवरण दर्ज करें

यह मूल रूप से धीरे-धीरे सिकुड़ते, चिकने बेलों के साथ एक भग्न यादृच्छिक चलना है। मैं उनमें से 75 को आकर्षित करता हूं, धीरे-धीरे पीछे से सफेद से काले रंग में बदलता है। फिर मैंने पूरी बात बताई, बेशर्मी से उसके लिए यहाँ Averroes का कोड एडाप्ट किया ।

गोल्फ: (सिर्फ इसलिए कि दूसरों ने फैसला किया)

import java.awt.*;import java.awt.image.*;import java.util.*;class P{static Random rand=new Random();public static void main(String[]a){float c=255;int i,j;Random rand=new Random();final BufferedImage m=new BufferedImage(800,600,BufferedImage.TYPE_INT_RGB);Graphics g=m.getGraphics();for(i=0;i++<75;g.setColor(new Color((int)c,(int)c,(int)c)),b(g,rand.nextInt(800),599,25+(rand.nextInt(21-10)),rand.nextInt(7)-3),c-=3.4);for(i=0;i<800;i++)for(j=0;j<600;j++)if(((m.getRGB(i,j)>>>16)&0xFF)/255d<rand.nextFloat()*.7+.05)m.setRGB(i,j,0);else m.setRGB(i,j,0xFFFFFF);new Frame(){public void paint(Graphics g){setSize(800,600);g.drawImage(m,0,0,null);}}.show();}static void b(Graphics g,float x,float y,float s,float a){if(s>1){g.fillOval((int)(x-s/2),(int)(y-s/2),(int)s,(int)s);s-=0.1;float n,t,u;for(int i=0,c=rand.nextInt(50)<1?2:1;i++<c;n=a+rand.nextFloat()-0.5f,n=n<-15?-15:n>15?15:n,t=x+s/2*(float)Math.cos(n),u=y-s/2*(float)Math.sin(n),b(g,t,u,s,n));}}}

साने मूल कोड:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;

public class Paint {

    static int minSize = 1;
    static int startSize = 25;
    static double shrink = 0.1;
    static int branch = 50;
    static int treeCount = 75;

    static Random rand = new Random();
    static BufferedImage img;

    public static void main(String[] args) {
        img = new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);
        forest(img);
        dither(img);
        new JFrame() {
            public void paint(Graphics g) {
                setSize(800,600);
                g.drawImage(img,0,0,null);
            }
        }.show();
    }

    static void forest(BufferedImage img){
        Graphics g = img.getGraphics();
        for(int i=0;i<treeCount;i++){
            int c = 255-(int)((double)i/treeCount*256);
            g.setColor(new Color(c,c,c));
            tree(g,rand.nextInt(800), 599, startSize+(rand.nextInt(21-10)), rand.nextInt(7)-3);
        }
    }

    static void tree(Graphics g, double x, double y, double scale, double angle){
        if(scale < minSize)
            return;
        g.fillOval((int)(x-scale/2), (int)(y-scale/2), (int)scale, (int)scale);
        scale -= shrink;
        int count = rand.nextInt(branch)==0?2:1;
        for(int i=0;i<count;i++){
            double newAngle = angle + rand.nextDouble()-0.5;
            if(newAngle < -15) newAngle = -15;
            if(newAngle > 15) newAngle = 15;
            double nx = x + (scale/2)*Math.cos(newAngle);
            double ny = y - (scale/2)*Math.sin(newAngle);
            tree(g, nx, ny, scale, newAngle);
        }
    }

    static void dither(BufferedImage img) {
        for (int i=0;i<800;i++)
            for (int j=0;j<600;j++) {
                double lum = ((img.getRGB(i, j) >>> 16) & 0xFF) / 255d;
                if (lum <= threshold[rand.nextInt(threshold.length)]-0.2)
                    img.setRGB(i, j, 0xFF000000);
                else
                    img.setRGB(i, j, 0xFFFFFFFF);
            }
    }

    static double[] threshold = { 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64,
            0.65, 0.66, 0.67, 0.68, 0.69 };

}

एक और? ठीक है! इस एक को थोडा नीचे की ओर झुका हुआ है, इसलिए सामने वाले काले रंग के हैं।

यहाँ छवि विवरण दर्ज करें

दुर्भाग्य से, बेल की परतों का बारीक विवरण नहीं दिखाता है। यहां केवल तुलना के लिए एक संक्षिप्त संस्करण है:

यहाँ छवि विवरण दर्ज करें


1
अच्छा लगा। खुशी है कि मेरा कोड मददगार था;)
एवरोसेस

1
मैं नियमों में कहीं भी पढ़ता हूं कि डाइटिंग की आवश्यकता है। मुझे लगता है कि undithered संस्करण अधिक सुंदर लग रहा है।
लार्स एबर्ट

4
@ लार्स डिटेरिंग की जरूरत नहीं है, लेकिन: केवल काले और सफेद रंग का इस्तेमाल किया जा सकता है, किसी भी ग्रे वैल्यू की अनुमति नहीं है ....
मैनुअल केस्टेन

31

जावास्क्रिप्ट + HTML - गोल्फ नहीं

@ मैन्यूल कान्स्टन के एल्गोरिथ्म की एक जावास्क्रिप्ट पोर्टिंग - यह आश्चर्यजनक है कि ये पेड़ कितने अच्छे लगते हैं।

बस कुछ अलग करने के लिए, मैं छवि को रंग में खींचता हूं, फिर अंतिम चरण में बी / डब्ल्यू तक।

मुझे पता नहीं क्यों, लेकिन मेरा जंगल कम अंधेरा है और मैनुएल के लिए कम भयावह सम्मान है।

JSfiddle के साथ परीक्षण करें या नीचे नया स्निपेट चलाएं । यह तेज नहीं है। धैर्य रखें और जंगल को बढ़ते हुए देखें।

वन १ वन 1 रंग

वन २ वन २ रंग

W=800
H=600
canvas.width = W;
canvas.height = H;

var ctx = canvas.getContext("2d");

R=function(m) { return m * Math.random()};
RAD=function(deg) { return deg / 180 * Math.PI};
LIMIT=function(x, min, max) {return x < min ? min : x > max ? max : x};
var SPEED = 0.01, HEIGHT = 11.0;

// Ground
var grd = ctx.createLinearGradient(0,0,0,H);
grd.addColorStop(0,"#88ccff");
grd.addColorStop(0.45,"#ffffee");
grd.addColorStop(0.5,"#80cc80");
grd.addColorStop(1,"#001100");
ctx.fillStyle = grd;
ctx.fillRect(0,0, W,H);


Plot = function(dist, side, h, s, alpha, diam)
{
    var x, y, a1,a2,scale = H/4 * 3.5 / dist, 
        x0 = side * scale + s * scale + W/2,
        y0 = H/2 + 2.5*scale - h*scale;
    
    k = dist
    if (diam > 0.05) {
        red = k*3|0;     
        green = k|0;
        a1=alpha+1
        a2=alpha-1
    }
    else
    {
        green= 80+(1-diam)*k*2|0;
        red = k|0;
        a1=0;
        a2=2*Math.PI;
    }
    diam *= scale;
    h *= scale;
    s *= scale;
    ctx.beginPath();
    ctx.arc(x0,y0,diam/2, a1,a2);//lpha-1, alpha+1);//0,2*Math.PI);
    ctx.fillStyle = 'rgb('+red+','+green+',0)';
    ctx.fill();
}

Grow = function(dist, side, h, s, alpha, grown)
{
    var diam, branchLength = 0.0;
    diam = (1.0 - grown / HEIGHT) * 0.5;
    do
    {
        alpha += R(RAD(3)) - RAD(1.5);
        h += Math.sin(alpha) * SPEED;
        s += Math.cos(alpha) * SPEED;
        branchLength += SPEED;
        grown += SPEED;
        diam = (1.0 - grown / HEIGHT) * 0.5;
        Plot(dist, side, h, s, alpha, diam);
    } while(branchLength < 5 * diam + R(6 * diam) && diam > 0.02);

    if (diam > 0.02)
    {
        var br = 0;

        if(R(10) > 2) br++,Grow(dist, side, h, s, alpha + RAD(15) + R(RAD(20)), grown);
        if(R(10) > 2) br++,Grow(dist, side, h, s, alpha - RAD(15) - R(RAD(20)), grown);
        if(R(10) < 2 || br == 0) Grow(dist, side, h, s, alpha - RAD(2.5) + R(RAD(5)), grown);
    }
}

trees=[]
for(i = 0; i < 300; ++i) trees.push({ z: 1+R(70), s:R(120)-60 });
trees.sort( function (a,b) { return a.z - b.z} );

Draw = function()
{
    t = trees.pop();
    if (t)
    {
        Grow(t.z, t.s, 0, 0, RAD(90), 0);
        setTimeout(Draw, 100);
    }
    else 
    {
        var e,c,d,p,i,l, img = ctx.getImageData(0,0,W,H);
        l = img.data.length;
        for (i = 0; i < l-W*4-4; i+=4)
        {
            c = (img.data[i]+img.data[i+1])/2|0
            c = img.data[i]
            d = c > 120 + R(16) ? 255 : 0
            e = c - d;
            img.data[i]=img.data[i+1]=img.data[i+2]=d
            c = (img.data[i+4]+img.data[i+5])/2|0
            
            c = LIMIT(c + ((e*7)>>4),0,255)
            img.data[i+4]=img.data[i+5]=img.data[i+6]=c
            p = i+W*4
            c = (img.data[p-4]+img.data[p-3])/2|0
            c = LIMIT(c + ((e*3)>>4),0,255)
            img.data[p-4]=img.data[p-3]=img.data[p-2]=c
            c = (img.data[p]+img.data[p+1])/2|0
            c = LIMIT(c+ ((e*5)>>4),0,255)
            img.data[p]=img.data[p+1]=img.data[p+2]=c
            c = (img.data[p+4]+img.data[p+5]*2)/3|0
            c = LIMIT(c + (e>>4),0,255)
            img.data[p+4]=img.data[p+5]=img.data[p+6]=c
    
        }
        bwcanvas.width = W;
        bwcanvas.height = H;
        var bwx = bwcanvas.getContext("2d");
        bwx.putImageData(img,0,0);
    }
}

setTimeout(Draw, 10);
<canvas id='bwcanvas'  width="2" height="2"></canvas>
<canvas id='canvas'  width="2" height="2"></canvas>


2
यह जमीन है, मुझे लगता है। मैनुअल के पेड़ जमीन में घुल-मिल जाते हैं, जिससे धुंधली, चमकदार उपस्थिति बनती है। आपका ग्राउंड प्लेन हल्का है, जो उच्च विपरीत के साथ अधिक हवादार उपस्थिति देता है। इसके अलावा, ठोस रंग का आकाश और मैनुअल के चित्रों में दूरी फीका एक अस्पष्ट कोहरे या धुंध की उपस्थिति बनाने में मदद करता है। (माइंड
यू

हाँ, यह मैनुअल की गहरी लकड़ियों का एक बाग है।
छायाकार

23

संदर्भ मुक्त कला 3 (1133)

CF एक सदिश ग्राफिक्स रेंडरिंग लैंग्वेज है, इसलिए मैं एंटी-एलिसिंग से बच नहीं सकता। मैंने उस जगह पर कई (चर N) बार एक ही जगह पर वर्ग बनाकर काम किया । कोहरे को यादृच्छिक स्थानों पर छोटे वर्गों को आकर्षित करके किया जाता है।

startshape main

W = 80*0.6
H = 60*0.6

N = 3

CF::Background = [ b -1 ]
CF::Size = [ x 0 y -20 s W H ]
CF::Color = 0
CF::ColorDepth = 16
CF::MinimumSize = 0.6

shape main {
  transform [ z 0 y (H/2) b 1 ]
  loop 30 [ z -1 y -2 ] {
    loop 200000 []
      SQUARE1 [ s (0.1/3) x -W..W y -H..H z -0.5..0.5 ]
  }

  transform [ b -1 z 3 ]
  loop 14 [[ s 1.1 y -0.8..-1 s 0.6 z -3 ]] {
    loop 14 [] tree [ x (-30..-20) z (-3..3) ]
    loop 14 [] tree [ x (20..30) z (-3..3) ]
  }
}

shape tree {
  branch [ ]
}

shape branch
rule 7 {
  transform [ s (1..2) 1]
  SQUARE1 [ ]

  branch [ y (0.2..0.3) x (-0.05..0.05) s 0.994 r (-6..6) z (-0.3..0.3)  ]
  branch1 [ b 0.001 z -2 r -20..20 ]
}
rule 0.001 { }
rule 0.3 { branch [ r 4..20 ] }
rule 0.3 { branch [ r -4..-20 ] }

shape branch1
rule 90 { }
rule { branch [ r -22..22 s 0.8..1 ] }

path SQUARE1 {
  MOVETO( 0.5,  0.5)
  LINETO(-0.5,  0.5)
  LINETO(-0.5, -0.5)
  LINETO( 0.5, -0.5)
  CLOSEPOLY()
  loop N [] FILL()[]
}

shape S {
  SQUARE [ a -1 ]
  loop 1000 [ ] SQUARE [ x (-0.5..0.5) y (-0.5..0.5) s 0.01..0.001 ]
}

यहाँ छवि विवरण दर्ज करें

विभिन्न संख्याओं का उपयोग करते हुए अधिक रेंडर यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें


1
मुझे लगता है कि कोई विकल्प नहीं है, लेकिन आउटपुट अभी भी काला / सफेद होना चाहिए।
Geobits

1
क्या आपको कोई रास्ता नहीं मिल रहा है? जैसा कि है, यह मान्य उत्तर नहीं है।
edc65

1
आपको कम नहीं करना है, लेकिन आपको केवल 2 रंगों का उपयोग करना है - काले और सफेद। ग्रेस्केल का उपयोग नियमों से मेल नहीं खाता है। प्रश्न को अस्पष्टता को दूर करने के लिए संपादित किया गया है। मैं इसे प्राप्त करने के लिए कुछ विधि का उपयोग करने की सलाह दूंगा, चाहे वह डिटेरिंग हो या न हो, ताकि बहुत अधिक डाउनवोट आने से पहले आप अपना उत्तर संपादित कर सकें।
ट्राइकोप्लाक्स

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

1
यह अब प्रश्न की भावना में होने के बहुत करीब है।
त्रिकोप्लक्स

19

C: 301

यह कार्यक्रम PGM प्रारूप में एक सरल, अमूर्त छवि बनाता है । आप इसे GIMP से खोल सकते हैं।

int x,y,i,d,w;srand(time(NULL));unsigned char p[480000];FILE *f=fopen("a.pgm","w");fprintf(f,"P5\n800 600\n1\n");i=480000;while(i--)p[i]=i>240000|(i%800+i/800&3)!=0;i=100;while(i--){d=(11000-i*i)/99;y=300+1100/d;x=rand()%800;while(y--){w=300/d;while(w--)p[y*800+w+x]=0;}}fwrite(p, 1, 480000, f);fclose(f);

यहाँ एक उदाहरण रन है:उत्पन्न छवि


34
यह जंगल की तुलना में बारकोड की तरह दिखता है :)
सिल्वेस्टर

6
बारट्री जंगल उल्टा
फैब्रिकियो

5
नीचे स्क्रॉल करने पर मुझे लगा कि मेरा ब्राउज़र छवि को सही ढंग से प्रस्तुत करने में विफल रहा। यदि आपके बारकोड स्कैनर से स्कैन किए गए URL से आपको इस चालान से उपज मिलती है तो मैं आपको एक टन बोनस अंक दूंगा। सिवाय इसके कि यह एक यादृच्छिक जंगल नहीं होगा।
nwp

6
मैंने इसे स्कैन किया और मेरे बारकोड स्कैनर ने मुझे शाप दिया। धन्यवाद।
प्लाज़्मा एचएच

1
@nwp आप UPC डेटाबेस से एक यादृच्छिक कोड ले सकते हैं , हालाँकि।
स्केलेबल

18

जावा के साथ IFS

यह समाधान एक (प्रोटो) पेड़ का वर्णन करने के लिए एक Iterated फ़ंक्शन सिस्टम (IFS) का उपयोग करता है। IFS को 100 बार (= वन) लगाया जाता है। इससे पहले कि प्रत्येक पेड़ को चित्रित किया जाता है (जंगल में लगाया जाता है) IFS को थोड़ी सी जगह (यादृच्छिक चलने की शैली) में बदल दिया जाता है। इसलिए प्रत्येक पेड़ थोड़ा अलग दिखता है।

चित्र यादृच्छिक बीज से हैं:

  • -+८२४७३७४४३
  • -+१२२०८९७८७७
  • -+६४४४९२२१५
  • 1133984583

कोई dithering की जरूरत है।

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;

public class IFS {
    static Random random=new Random();
    static int BLACK = 0xff000000;
    static int treeCount = 100;
    static Random rand = new Random();
    static int Height = 600;
    static int Width = 800;
    static BufferedImage img = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_ARGB);

    static double[][] ifs=new double[][] {//Tree 3 {; Paul Bourke  http://ecademy.agnesscott.edu/~lriddle/ifskit/gallery/bourke/bourke.ifs
       {0.050000,  0.000000,  0.000000,  0.600000,  0.000000,  0.000000,  0.028000},
       {0.050000,  0.000000,  0.000000, -0.500000,  0.000000,  1.000000,  0.023256},
       {0.459627, -0.321394,  0.385673,  0.383022,  0.000000,  0.600000,  0.279070},
       {0.469846, -0.153909,  0.171010,  0.422862,  0.000000,  1.100000,  0.209302},
       {0.433013,  0.275000, -0.250000,  0.476314,  0.000000,  1.000000,  0.555814 /*Paul Bourke has: 0.255814*/},
       {0.421325,  0.257115, -0.353533,  0.306418,  0.000000,  0.700000,  0.304651 /*Paul Bourke has: 0.204651*/},
    };

    public static void main(String[] args) {
        int seed=random.nextInt();
        //seed=-1220897877;
        random=new Random(seed);
        for (int t = 0; t < treeCount; t++) {
            for (int i = 0; i < ifs.length; i++) {
                for (int j = 0; j < ifs[0].length; j++) {
                    ifs[i][j]=R(ifs[i][j]);
                }
            }
            tree(random.nextDouble(), 0.1*random.nextDouble());
        }
        JFrame frame = new JFrame(""+seed) {
            public void paint(Graphics g) {
                setSize(800,600);
                g.drawImage(img,0,0,null);
            }
        };
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static void tree(double x0, double dist) {
        double y0=Math.atan(dist+0.01);
        double scale=Math.atan(0.01)/y0;
        double x=0;
        double y=0;
        for (int n = 0; n < 200000/Math.pow(20*dist+1, 8); n++) {
            int k = select(ifs);
            double newx=ifs[k][0]*x + ifs[k][1]*y + ifs[k][2];
            double newy=ifs[k][3]*x + ifs[k][4]*y + ifs[k][5];
            x=newx;
            y=newy;
            newx= Width*(0.5*scale*newx+x0);
            newy= Height*((1-0.5*scale*newy)-y0-0.1);
            if (0<=newx && newx<Width && 0<=newy && newy<Height) {
                img.setRGB((int)newx, (int)newy, BLACK);
            }
        }
    }

    private static double R(double x) {
        return (1+ 0.01*random.nextGaussian())*x;
    }

    private static int select(double[][] ifs) {
        int k;
        double sum=0;
        for(k=0; k<ifs.length; k++) {
            sum+=ifs[k][6];
        }
        double r=sum*random.nextDouble();
        sum=ifs[0][6];
        for(k=0; k<ifs.length-1 && r>sum; k++) {
            sum+=ifs[k+1][6];
        }
        return k;
    }
}

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें


अंतिम चित्र सबसे अच्छे लगते हैं। हालाँकि मुझे लगता है कि आपको कम पेड़ों की कोशिश करनी चाहिए, क्योंकि अब हमेशा काले रंग का पहचान नहीं होता है, लेकिन किनारों पर यह बेहतर दिखता है।
सोमनीयम

"सुंदरता देखने वाले की नजर में है।" मैंने कई विविधताओं का परीक्षण किया। अंत में, मैं ट्रीकाउंट = 100 के साथ आया। मेरे समाधान की नकल करने और बदलने के लिए हर किसी का स्वागत है।
बॉब जीनोम

15

मैंने यहां पर कॉनिफ़र की एक अलग कमी देखी, इसलिए मैंने पायथन में एक साथ कुछ हैक किया।

from PIL import Image
import random

#Generates the seed for a tree
def makeSeed(y):
    random.seed()
    seed_x = random.randint(10, 590)
    seed_y = y
    width = random.randint(5, 10)
    height = random.randint(width*5, width*30)

    return (seed_x, seed_y, width, height)

#Grows the vertical components
def growStems(seed_data, pixel_field):
    seed_x = seed_data[0]
    seed_y = seed_data[1]
    width = seed_data[2]
    height = seed_data[3]
    for x in range(seed_x, seed_x+width):
        for y in range(seed_y-height, seed_y):
            pixel_field[x][y] = (0, 0, 0)
            #Dithering
            if seed_y > 300 and seed_y < 320:
                if (x+y)%2==0:
                    pixel_field[x][y] = (255, 255, 255)
            elif seed_y >= 320 and seed_y < 340:
                if (x+y)%4==0:
                    pixel_field[x][y] = (255, 255, 255)
            elif seed_y >= 340 and seed_y < 360:
                if (x+y)%8==0:
                    pixel_field[x][y] = (255, 255, 255)

    return pixel_field

#Grows the horizontal components
def growBranches(seed_data, pixel_field):
    seed_x = seed_data[0]
    seed_y = seed_data[1]
    width = seed_data[2]
    height = seed_data[3]
    branch_height = seed_y-height
    branch_width = width
    branch_length = 2
    max_prev = branch_length
    branches = []
    while(branch_height >= seed_y-height and branch_height < seed_y-(3*width) and branch_length < height/3):
        branches.append((branch_height, branch_width, branch_length))
        branch_height+= 4
        branch_length+=2
        #Gives the conifer unevenness to make it look more organic
        if random.randint(0,110) > 100 and branch_length > max_prev:
            max_prev = branch_length
            branch_length -= branch_length/4
    max_length = height/3


    for x in range(seed_x-max_length, seed_x+max_length):
        for y in range(seed_y-height, seed_y):
            for branch in branches:
                bh = branch[0]
                bw = branch[1]
                bl = branch[2]
                #Establishing whether a point is "in" a branch
                if x >= seed_x-bl+(width/2) and x <= seed_x+bl+(width/2):
                    if x > 1 and x < 599:
                        if y >= bh-(bw/2) and y <= bh+(bw/2):
                            if y < 400 and y > 0:
                                pixel_field[x][y] = (0, 0, 0)
                                #Dithering
                                if seed_y > 300 and seed_y < 320:
                                    if (x+y)%2==0:
                                        pixel_field[x][y] = (255, 255, 255)
                                elif seed_y >= 320 and seed_y < 340:
                                    if (x+y)%4==0:
                                        pixel_field[x][y] = (255, 255, 255)
                                elif seed_y >= 340 and seed_y < 360:
                                    if (x+y)%8==0:
                                        pixel_field[x][y] = (255, 255, 255)

    return pixel_field


def growTrees(n):
    pixel_field = [[(255, 255, 255) for y in range(400)] for x in range(600)]
    #Create the ground
    for i in range(600):    
        for j in range(400):
            if pixel_field[i][j]==(255,255,255) and j > 300:
                if (i+j)%2 == 0:
                    pixel_field[i][j]=(0,0,0)
    seed_ys=[]
    #Generates seeds for the trees and orders them back to front to make the dithering work
    for t in range(n):
        seed_ys.append(random.randint(300,390))
    seed_ys.sort()

    for s in range(len(seed_ys)):
        seed= makeSeed(seed_ys[s])
        pixel_field = growStems(seed, pixel_field)
        pixel_field = growBranches(seed, pixel_field)
    return pixel_field

def makeForest():
    forest = growTrees(25)
    img = Image.new( 'RGB', (600,400), "white") # create a new black image
    pixels = img.load() # create the pixel map
    for i in range(img.size[0]):    # for every pixel:
        for j in range(img.size[1]):
            if pixels[i,j]==(255,255,255) and j > 300:
                if (i+j)%2 == 0:
                    pixels[i,j]=(0,0,0)
            pixels[i,j] = forest[i][j] # set the colour accordingly

    img.save("Forest25.jpg")

if __name__ == '__main__':
    makeForest()

5 पेड़ों वाला जंगल 10 पेड़ों वाला जंगल 25 पेड़ों वाला जंगल

यह मेरा पहला कोड गोल्फ था, यह बहुत मजेदार था!


1
अछा लगता है! मुझें यह पसंद है।
टोनीस्नेपर

5

यह जवाब उतना सुंदर नहीं है जितना मुझे उम्मीद थी, लेकिन यह एक और अधिक 3D विचार के लिए एक पत्थर है जो मैं काम कर रहा हूं, और मुझे वास्तव में यह विचार पसंद है कि वास्तव में कौन से पेड़ों को संसाधन मिलते हैंयहाँ छवि विवरण दर्ज करें

package forest;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Forest extends Canvas{
    private int[] heights = new int[800];
    private BufferedImage buffered_image;
    File outputFile = new File("saved.png");
    Random r = new Random();
    public Forest() {
        buffered_image = new BufferedImage(800, 600,
                BufferedImage.TYPE_INT_RGB);
        for( int j = 0; j < 800; j++){
            heights[j] = -10000;
            for(int k = 0; k < 600; k++){
                buffered_image.setRGB(j, k, 0xFFFFFF);
            }
        }
        for(int i = 0; i < 7; i ++){
            heights[r.nextInt(800)] = 0;
        }

        this.setPreferredSize(new Dimension(800, 600));
        this.setSize(new Dimension(800, 600));
        for( int i = 0; i < 200000; i++){
            int x = r.nextInt(798) + 1;
            heights[x] =  Math.min(599, heights[x - 1] == heights[x + 1] ? heights[x] : Math.max(Math.max(heights[x - 1], heights[x]),heights[x + 1]) + 1);
            buffered_image.setRGB(x, Math.min(599, 600 - heights[x]), 0);
        } 

        try {

            ImageIO.write(buffered_image, "png", outputFile);
        } catch (IOException e) {

        }
        update();
    }
    public void repaint(){
        if(this.getGraphics() != null)
        paint(this.getGraphics());
    }


    public void paint(Graphics g) {
        g.drawImage(buffered_image, 0, 0, this);
    }

    public void update() {  
        repaint();
    }

    public static void main(String[] args) throws IOException {
        JFrame main_frame = new JFrame();
        main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel top_panel = new JPanel();
        top_panel.setLayout(new BorderLayout());
        Forest s = new Forest();
        top_panel.add(s, BorderLayout.CENTER);
        main_frame.setContentPane(top_panel);

        main_frame.pack();
        main_frame.setVisible(true);
    }

}

6
शायद इसे देवदार के पेड़ों के समान बनाने के लिए इसे लंबवत रूप से फ्लिप करें?
सोमनियम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.