임의의 흑백 숲 그리기 수 없습니다. 순전히 알고리즘 적으로 이미지를 생성해야합니다. 2

당신의 임무는 800×600 흑백 이미지를 숲과 유사한 것으로 그릴 프로그램을 작성하는 것입니다.

이것처럼 (디더링 된 사진입니다) :

규칙

  • 기존 이미지를 사용할 수 없습니다. 순전히 알고리즘 적으로 이미지를 생성해야합니다.
  • 2 가지 색상 만 사용-흑백 (회색조 없음)
  • 프로그램이 실행될 때마다 이미지는 새로운 것이어야합니다-매번 무작위
  • 하나의 나무는 숲이 아닙니다 (5 그루의 나무를 말하십시오)
  • 나무 / 숲을 그리기위한 특수 라이브러리는 허용되지 않습니다
  • 대부분의 투표로 승리


답변

C : 3863 1144 1023 999 942 927

원래 솔루션은 실행 당 2 개의 pnm 파일을 저장합니다 (하나는 디더링 전에 g가 추가 된 파일). 디더링은 처음 몇 줄에서는 아름답 지 않았기 때문에 필요한 것보다 많은 줄을 렌더링하고 출력하는 동안 잘라낼 수있는 해킹이 있습니다.

골프 솔루션은 더 간단한 디더링을 가지고 디더링 된 이미지 만 저장합니다. (gcc -std = c11 -pedantic -Wall -Wextra에 대한 경고 없음)

3 개의 원래 프로그램 실행 및 1 회 실행 된 골프 버전의 이미지 예 (마지막 이미지)

예 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);
  }


답변

자바 정글

(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));}}}

Sane 원래 코드 :

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 };

}

하나 더? 괜찮아! 이것은 디더링을 약간 낮추었으므로 앞면의 검은 색이 훨씬 평평합니다.

여기에 이미지 설명을 입력하십시오

불행히도, 디더는 포도 나무 층의 세부 사항을 보여주지 않습니다. 그레이 스케일 버전은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


답변

자바 스크립트 + HTML-골프를 타지 않음

@Manuel Kansten 알고리즘의 자바 스크립트 포팅-이 나무가 얼마나 잘 보이는지 놀랍습니다.

다른 것을하기 위해 이미지를 컬러로 그린 다음 마지막 단계에서 흑백으로 디더링합니다.

나는 왜 그런지 모르겠지만 내 숲은 마누엘에 대한 덜 어둡고 덜 무섭습니다.

JSfiddle로 테스트 하거나 아래 의 새 코드 조각을 실행하십시오 . 빠르지 않습니다. 인내심을 갖고 숲이 자라는 것을보십시오.

숲 1
포레스트 1 색

숲 2
포레스트 2 컬러

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>


답변

문맥 자유 예술 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 ]
}

여기에 이미지 설명을 입력하십시오

다른 숫자를 사용하여 더 많은 렌더링
여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오


답변

C : 301

이 프로그램은 PGM 형식 의 단순하고 추상적 인 이미지를 만듭니다 . 김프로 열 수 있습니다.

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);

다음은 예제 실행입니다.생성 된 이미지


답변

Java를 사용한 IFS

이 솔루션은 IFS (Iterated Function System)를 사용하여 하나의 (프로토) 트리를 설명합니다. IFS는 100 번 적용됩니다 (= 포리스트). 각 나무를 채색하기 전에 (숲에 심기) IFS가 약간 변경됩니다 (임의의 보행 스타일). 따라서 각 나무는 약간 다르게 보입니다.

사진은 무작위 씨앗에서 나왔습니다.

  • -824737443
  • -1220897877
  • -644492215
  • 1133984583

디더링이 필요하지 않습니다.

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;
    }
}

여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오


답변

나는 여기에 침엽수가 부족하다는 것을 알았으므로 파이썬에서 무언가를 해킹했습니다.

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 그루의 숲

이것은 나의 첫번째 코드 골프이었다, 그것은 많은 재미이었다!