๋น์ ์ ์๋ฌด๋ 800ร600 ํ๋ฐฑ ์ด๋ฏธ์ง๋ฅผ ์ฒ๊ณผ ์ ์ฌํ ๊ฒ์ผ๋ก ๊ทธ๋ฆด ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๊ฒ์ ๋๋ค.
์ด๊ฒ์ฒ๋ผ (๋๋๋ง ๋ ์ฌ์ง์ ๋๋ค) :
๊ท์น
- ๊ธฐ์กด ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์์ ํ ์๊ณ ๋ฆฌ์ฆ ์ ์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ์์ฑํด์ผํฉ๋๋ค.
- 2 ๊ฐ์ง ์์ ๋ง ์ฌ์ฉ-ํ๋ฐฑ (ํ์์กฐ ์์)
- ํ๋ก๊ทธ๋จ์ด ์คํ๋ ๋๋ง๋ค ์ด๋ฏธ์ง๋ ์๋ก์ด ๊ฒ์ด์ด์ผํฉ๋๋ค-๋งค๋ฒ ๋ฌด์์
- ํ๋์ ๋๋ฌด๋ ์ฒ์ด ์๋๋๋ค (5 ๊ทธ๋ฃจ์ ๋๋ฌด๋ฅผ ๋งํ์ญ์์ค)
- ๋๋ฌด / ์ฒ์ ๊ทธ๋ฆฌ๊ธฐ์ํ ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ฉ๋์ง ์์ต๋๋ค
- ๋๋ถ๋ถ์ ํฌํ๋ก ์น๋ฆฌ
๋ต๋ณ
C : 3863 1144 1023 999 942 927
์๋ ์๋ฃจ์ ์ ์คํ ๋น 2 ๊ฐ์ pnm ํ์ผ์ ์ ์ฅํฉ๋๋ค (ํ๋๋ ๋๋๋ง ์ ์ g๊ฐ ์ถ๊ฐ ๋ ํ์ผ). ๋๋๋ง์ ์ฒ์ ๋ช ์ค์์๋ ์๋ฆ๋ต ์ง ์์๊ธฐ ๋๋ฌธ์ ํ์ํ ๊ฒ๋ณด๋ค ๋ง์ ์ค์ ๋ ๋๋งํ๊ณ ์ถ๋ ฅํ๋ ๋์ ์๋ผ๋ผ ์์๋ ํดํน์ด ์์ต๋๋ค.
๊ณจํ ์๋ฃจ์ ์ ๋ ๊ฐ๋จํ ๋๋๋ง์ ๊ฐ์ง๊ณ ๋๋๋ง ๋ ์ด๋ฏธ์ง ๋ง ์ ์ฅํฉ๋๋ค. (gcc -std = c11 -pedantic -Wall -Wextra์ ๋ํ ๊ฒฝ๊ณ ์์)
3 ๊ฐ์ ์๋ ํ๋ก๊ทธ๋จ ์คํ ๋ฐ 1 ํ ์คํ ๋ ๊ณจํ ๋ฒ์ ์ ์ด๋ฏธ์ง ์ (๋ง์ง๋ง ์ด๋ฏธ์ง)
๊ณจํ ๋ฒ์
#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๋ก ํ ์คํธ ํ๊ฑฐ๋ ์๋ ์ ์ ์ฝ๋ ์กฐ๊ฐ์ ์คํํ์ญ์์ค . ๋น ๋ฅด์ง ์์ต๋๋ค. ์ธ๋ด์ฌ์ ๊ฐ๊ณ ์ฒ์ด ์๋ผ๋ ๊ฒ์๋ณด์ญ์์ค.
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()
์ด๊ฒ์ ๋์ ์ฒซ๋ฒ์งธ ์ฝ๋ ๊ณจํ์ด์๋ค, ๊ทธ๊ฒ์ ๋ง์ ์ฌ๋ฏธ์ด์๋ค!