Buat Pohon Natal yang scalable [ditutup]


95

Tantangan Anda: Buat pohon Natal. Ukuran harus dipilih dengan beberapa metode input, tetapi tidak harus terkait langsung dengan bagian pohon apa pun; namun, input yang lebih besar harus menghasilkan pohon yang lebih besar.

Bagaimana Anda bisa membuatnya? Anda dapat membuat pohon sesuka Anda, selain dengan mencetak karakter unicode untuk pohon , seperti ouputting gambar, seni ascii, dengan aspek lain, dll. Apa pun yang Anda lakukan, ingat bahwa ini adalah , jadi Jadilah kreatif.

Jawaban dengan paling banyak dukungan pada akhir Desember menang, tetapi saya akan menerima yang lain jika lebih tinggi


1
Pertanyaan bagus;)
Timtech

1
Sayang sekali dekorasi tidak wajib!
o0 '.

@ Lohoris Saya pikir baik bahwa mereka tidak wajib. Dengan cara ini, orang dapat melakukan apa yang mereka inginkan, dan pohon fraktal yang brilian itu adalah jawaban yang sah.
Justin

@ Quincunx Anda dapat menambahkan dekorasi bahkan ke pohon fraktal ...
o0 '.

@ Lohoris ya, tapi mereka banyak apa adanya. Penulis pohon-pohon itu dapat menambahkan dekorasi jika mereka mau, tapi saya lebih suka tidak memerlukannya.
Justin

Jawaban:


92

Python

Pohon Natal fraktal menggunakan paket penyu:

masukkan deskripsi gambar di sini

n = input()*1.

from turtle import *
speed("fastest")
left(90)
forward(3*n)
color("orange", "yellow")
begin_fill()
left(126)
for i in range(5):
    forward(n/5)
    right(144)
    forward(n/5)
    left(72)
end_fill()
right(126)

color("dark green")
backward(n*4.8)
def tree(d, s):
    if d <= 0: return
    forward(s)
    tree(d-1, s*.8)
    right(120)
    tree(d-3, s*.5)
    right(120)
    tree(d-3, s*.5)
    right(120)
    backward(s)
tree(15, n)
backward(n/2)

import time
time.sleep(60)

n adalah parameter ukuran, pohon yang ditampilkan adalah untuk n = 50. Butuh satu atau dua menit untuk menggambar.


2
Ini terlihat indah:)
Soner Gönül

80

JavaScript

masukkan deskripsi gambar di sini

Perlihatkan pohon animasi online .

var size = 400;

var canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
document.body.appendChild(canvas);

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

var p3d = [];

var p = [Math.random(), Math.random(), Math.random(), 0];

for (var i = 0; i < 100000; i++) {
    p3d.push([p[0],p[1],p[2],p[3]]);
    var t = Math.random();
    if (t<0.4) {
        _y = 0.4 * p[1];
        _x = 0.1 * p[0];
        _z = 0.6 * p[2];
        var r = Math.floor(3*t/0.4)/3.0;
        var rc = Math.cos(Math.PI*2.0*r);
        var rs = Math.sin(Math.PI*2.0*r);
        p[1] = _x+0.1*r+0.5*_y*_y;
        p[0] = _y*rc+_z*rs;
        p[2] = _z*rc-_y*rs;
        p[3] = 0.2*t + 0.8*p[3];
    } else {
        p[1] = 0.2 + 0.8*p[1];
        p[0] = 0.8 * p[0];
        p[2] = 0.8 * p[2];
        p[3] = 0.2 + 0.8*p[3];
    }
}

var rot = 0.0;

function render() {
    rot = rot + 0.1;
    var rc = Math.cos(rot);
    var rs = Math.sin(rot);

    ctx.strokeStyle='#FF7F00';
    ctx.lineWidth=2;
    ctx.beginPath();
    ctx.moveTo(size/2,size/8);
    ctx.lineTo(size/2,size*15/16);
    ctx.stroke();

    var img = ctx.getImageData(0, 0, size, size);
    for (var j = 0; j < size*size; j++) {
        img.data[4*j+0] = 0.5*img.data[4*j+0];
        img.data[4*j+1] = 0.5*img.data[4*j+1];
        img.data[4*j+2] = 0.5*img.data[4*j+2];
        img.data[4*j+3] = 255;
    }

    for (var i = 0; i < p3d.length; i++) {
        var px = p3d[i][0];
        var py = 0.5 - p3d[i][1];
        var pz = p3d[i][2];
        var col = Math.floor(128.0*p3d[i][3]);

        var _x = rc*px + rs*pz;
        var _z = rc*pz - rs*px;

        var z = 3.0 * size / (_z + 4.0);
        var x = size / 2 + Math.round(_x * z);        
        var y = size / 2 + Math.round(py * z);

        if(x>=0&&y>=0&&x<size&&y<size) {
            img.data[4 * (y * size + x) + 0] = col;
            img.data[4 * (y * size + x) + 1] = 128+col;
            img.data[4 * (y * size + x) + 2] = col;
            img.data[4 * (y * size + x) + 3] = 255;
        }
    }

    ctx.putImageData(img, 0, 0);
}

setInterval(render, 1000 / 30);

Saya suka, tetapi Anda harus menambahkan bagasi.
Fels

1
@Fels menambahkan trunk
Howard

2
Ini sangat mengesankan, tapi ada apa dengan piksel hijau yang mengelilingi pohon? Saya tidak menyadari bahwa Santa memiliki peri hijau kecil yang bisa terbang. (mereka tidak mengurangi keindahan jawaban Anda, tetapi saya ingin tahu dari mana asalnya)
Justin

@ Quincunx: Mereka tampaknya menjadi titik sampel awal sebelum iterasi bertemu. Melewati 100 poin pertama akan menghilangkannya.
Ilmari Karonen

2
Benar-benar keren, tapi itu tidak cukup terlihat seperti pohon Natal. Itu lebih mirip tongkat dengan beberapa daun pakis menempel padanya. Selain itu, bisakah Anda membuat tampilan perlahan bergulir di sepanjang sumbu y, sehingga 3D-ness lebih jelas?
The Guy with The Hat

76

Namun pohon Bahasa Mathematica / Wolfram lain berdasarkan jawaban Vitaliy :

PD = .5;
s[t_, f_] := t^.6 - f
dt[cl_, ps_, sg_, hf_, dp_, f_, flag_] :=
    Module[{sv, basePt},
           {PointSize[ps],
            sv = s[t, f];
            Hue[cl (1 + Sin[.02 t])/2, 1, .3 + sg .3 Sin[hf sv]],
            basePt = {-sg s[t, f] Sin[sv], -sg s[t, f] Cos[sv], dp + sv};
            Point[basePt],
           If[flag,
              {Hue[cl (1 + Sin[.1 t])/2, 1, .6 + sg .4 Sin[hf sv]], PointSize[RandomReal[.01]],
               Point[basePt + 1/2 RotationTransform[20 sv, {-Cos[sv], Sin[sv], 0}][{Sin[sv], Cos[sv], 0}]]},
              {}]
          }]

frames = ParallelTable[
                       Graphics3D[Table[{
                                         dt[1, .01, -1, 1, 0, f, True], dt[.45, .01, 1, 1, 0, f, True],
                                         dt[1, .005, -1, 4, .2, f, False], dt[.45, .005, 1, 4, .2, f, False]},
                                        {t, 0, 200, PD}],
                                  ViewPoint -> Left, BoxRatios -> {1, 1, 1.3}, 
                                  ViewVertical -> {0, 0, -1},
                                  ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}}, Boxed -> False,
                                  PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}}, Background -> Black],
                       {f, 0, 1, .01}];

Export["tree.gif", frames]

pohon Natal


7
Ini yang terbaik !!
Murta

63

Javascript

Output dari contoh kode yang diberikan

Ini golf kode pertamaku!

var a=40,b=8,c=13,o="<div style='font-family:monospace;text-align:center;color:#094'>",w=1,x=0,y="|#|<br>";for(i=1;i<a;i++){for(j=0;j<w;j++){x%c==0?o+="<span style='color:#D00'>O</span>":o+="+";x++;}i%b==0?w-=4:w+=2;o+="<br>";}document.write(o+"<span style='color:#640'>"+y+y+y+"</span></div>");

Muncul di 295 Karakter.

Ukuran dan dekorasi pohon diatur oleh variabel a, b, c:

  • a mengatur jumlah baris di pohon
  • b mengatur jumlah baris antara penurunan lebar (tetapkan rendah untuk pohon kurus, tinggi untuk pohon gemuk). Harus lebih besar atau sama dengan 3.
  • c menetapkan jumlah pernak-pernik (set nol untuk tidak ada, 1 untuk pernak-pernik saja, angka yang lebih tinggi untuk penempatan pernak-pernik yang kurang padat)

Ini terlihat paling baik ketika a adalah kelipatan b, seperti pada contoh.

Rekatkan ke konsol untuk membuat pohon. Terlihat lebih baik dari jauh!


1
dikurangi menjadi 264a=40,b=8,c=13,o="<p style='font:monospace;color:#094' align='center'>",w=1,x=0,y="|#|<br>";for(i=1;i<a;i++){for(j=0;j<w;j++){x%c==0?o+="<b style='color:red'>O</b>":o+="+";x++;}i%b==0?w-=4:w+=2;o+="<br>";}document.write(o+"<b style='color:#640'>"+y+y+y+"</b></p>");
user1886419

4
Anda benar-benar bermain golf di kontes popularitas? Wow, saya akan menulis kode yang mudah dibaca (lebih mudah untuk dikodekan). +1
Justin

7
ungh. Anda menggunakan doc.write? Tidak ada +1 dari saya.
John Dvorak

2
@ JanDvorak, Kenapa tidak? Saya pikir ini golf .....
Pacerier

62

C ++

Mari kita membuatnya dalam semangat IOCCC dan memiliki kode dalam bentuk pohon juga! : D

#include <iostream>
using namespace std;

               int
             main(){
              int a
                ; 
               cin
             >>a;int
           w=a*2+5;for
             (int x=
           0;x<a;++x){
         for(int y=2;y>=
       0;--y){for(int z=0;
           z<a+y-x;++z
        ){cout<<" ";}for(
     int z=0;z<x*2-y*2+5;++z
        ){cout<<".";}cout
      <<endl;}}for(int x=0;
    x<w/5+1;++x){for(int z=0;
  z<w/3+1;++z){cout<<" ";}for(
int z=0;z<w-(w/3+1)*2;z+=1){cout
           <<"#";}cout
           <<endl;;;}}

Mengambil bilangan bulat sebagai input, dan mengembalikan pohon Natal dengan banyak "tingkat tumpukan". Misalnya, input dari

5

Pengembalian:

       .
      ...
     .....
      ...
     .....
    .......
     .....
    .......
   .........
    .......
   .........
  ...........
   .........
  ...........
 .............
      ###
      ###
      ###
      ###

contoh keluaran?
John Dvorak

32
Kode ini lebih mirip pohon chrismas daripada hasilnya ...
Denys Séguret

2
@dystroy sebagai catatan, instruksi tidak mengatakan itu adalah output yang harus menentang pohon.
Pierre Arlaud

4
@ ArchlaudPierre: Tapi, ukurannya harus disesuaikan, yang tidak mungkin hanya dengan kode sumber. Saya dapat membuat program yang mengeluarkan kode program dalam bentuk pohon Natal yang menghasilkan pohon Natal yang sebenarnya , tetapi saya membayangkan itu akan sangat sulit tanpa menggunakan hanya menyisipkan titik koma di mana-mana.
Joe Z.

1
Jika Anda meletakkan a *di atas pohon (kode sumber), Anda akan memiliki +1 saya.
Fabricio

61

Javascript

Generator pohon cemara prosedural sepenuhnya 3D quasirealistic.

Menampilkan: konfigurasi ekstensif dengan lebih banyak opsi konfigurasi hadir dalam kode; batang zig-zag; cabang bercabang; animasi pertumbuhan; rotasi pohon yang sudah dewasa.

Tidak menampilkan: jQuery, Underscore.js atau perpustakaan lainnya; ketergantungan perangkat keras - hanya dukungan kanvas yang diperlukan; kode berantakan (setidaknya itu maksudnya)

Halaman langsung: http://fiddle.jshell.net/honnza/NMva7/show/

Edit halaman: http://jsfiddle.net/honnza/NMva7/

tangkapan layar:

pohon cemara

HTML:

<canvas id=c width=200 height=300 style="display:none"></canvas>
<div id=config></div>

Javascript:

var TAU = 2*Math.PI,
    deg = TAU/360,

    TRUNK_VIEW      = {lineWidth:3, strokeStyle: "brown", zIndex: 1},
    BRANCH_VIEW     = {lineWidth:1, strokeStyle: "green", zIndex: 2},
    TRUNK_SPACING   = 1.5,
    TRUNK_BIAS_STR  = -0.5,
    TRUNK_SLOPE     = 0.25,
    BRANCH_LEN      = 1,
    BRANCH_P        = 0.01,
    MIN_SLOPE       = -5*deg,
    MAX_SLOPE       = 20*deg,
    INIT_SLOPE      = 10*deg,
    MAX_D_SLOPE     =  5*deg,
    DIR_KEEP_BIAS   = 10,
    GROWTH_MSPF     = 10, //ms per frame
    GROWTH_TPF      = 10, //ticks per frame
    ROTATE_MSPF     = 10,
    ROTATE_RPF      = 1*deg; //radians per frame

var configurables = [
//    {key: "TRUNK_SPACING", name: "Branch spacing", widget: "number",
//     description: "Distance between main branches on the trunk, in pixels"},
    {key: "TRUNK_BIAS_STR", name: "Branch distribution", widget: "number",
     description: "Angular distribution between nearby branches. High values tend towards one-sided trees, highly negative values tend towards planar trees. Zero means that branches grow in independent directions."},
    {key: "TRUNK_SLOPE", name: "Trunk slope", widget: "number",
     description: "Amount of horizontal movement of the trunk while growing"},
    {key: "BRANCH_P", name: "Branch frequency", widget: "number",
     description: "Branch frequency - if =1/100, a single twig will branch off approximately once per 100 px"},
    {key: "MIN_SLOPE", name: "Minimum slope", widget: "number", scale: deg,
     description: "Minimum slope of a branch, in degrees"},
    {key: "MAX_SLOPE", name: "Maximum slope", widget: "number", scale: deg,
     description: "Maximum slope of a branch, in degrees"},
    {key: "INIT_SLOPE", name: "Initial slope", widget: "number", scale: deg,
     description: "Angle at which branches leave the trunk"},
    {key: "DIR_KEEP_BIAS", name: "Directional inertia", widget: "number",
     description: "Tendency of twigs to keep their horizontal direction"},
    {get: function(){return maxY}, set: setCanvasSize, name: "Tree height",
     widget:"number"}
    ];

var config = document.getElementById("config"),
    canvas = document.getElementById("c"),
    maxX   = canvas.width/2,
    maxY   = canvas.height,
    canvasRatio = canvas.width / canvas.height,
    c;

function setCanvasSize(height){
    if(height === 'undefined') return maxY;
    maxY = canvas.height = height;
    canvas.width = height * canvasRatio;
    maxX = canvas.width/2;
x}

var nodes = [{x:0, y:0, z:0, dir:'up', isEnd:true}], buds = [nodes[0]],
    branches = [],
    branch,
    trunkDirBias = {x:0, z:0};

////////////////////////////////////////////////////////////////////////////////

configurables.forEach(function(el){
    var widget;
    switch(el.widget){
        case 'number':
            widget = document.createElement("input");
            if(el.key){
                widget.value = window[el.key] / (el.scale||1);
                el.set = function(value){window[el.key]=value * (el.scale||1)};
            }else{
                widget.value = el.get();
            }
            widget.onblur = function(){
                el.set(+widget.value);
            };
            break;
        default: throw "unknown widget type";
    }
    var p = document.createElement("p");
    p.textContent = el.name + ": ";
    p.appendChild(widget);
    p.title = el.description;
    config.appendChild(p);
});
var button = document.createElement("input");
button.type = "button";
button.value = "grow";
button.onclick = function(){
    button.value = "stop";
    button.onclick = function(){clearInterval(interval)};
    config.style.display="none";
    canvas.style.display="";
    c=canvas.getContext("2d");
    c.translate(maxX, maxY);                
    c.scale(1, -1);
    interval = setInterval(grow, GROWTH_MSPF);
}
document.body.appendChild(button);
function grow(){
    for(var tick=0; tick<GROWTH_TPF; tick++){
        var budId = 0 | Math.random() * buds.length,
            nodeFrom = buds[budId], nodeTo, branch,
            dir, slope, bias

        if(nodeFrom.dir === 'up' && nodeFrom.isEnd){
            nodeFrom.isEnd = false; 
            rndArg = Math.random()*TAU;
            nodeTo = {
                x:nodeFrom.x + TRUNK_SPACING * TRUNK_SLOPE * Math.sin(rndArg),
                y:nodeFrom.y + TRUNK_SPACING,
                z:nodeFrom.z + TRUNK_SPACING * TRUNK_SLOPE * Math.cos(rndArg), 
                dir:'up', isEnd:true}
            if(nodeTo.y > maxY){
                console.log("end");
                clearInterval(interval);
                rotateInit();
                return;
            }
            nodes.push(nodeTo);
            buds.push(nodeTo);
            branch = {from: nodeFrom, to: nodeTo, view: TRUNK_VIEW};
            branches.push(branch);
            renderBranch(branch);
        }else{ //bud is not a trunk top
            if(!(nodeFrom.dir !== 'up' && Math.random() < BRANCH_P)){
                buds.splice(buds.indexOf(nodeFrom), 1)
            }
            nodeFrom.isEnd = false; 
            if(nodeFrom.dir === 'up'){
                bias = {x:trunkDirBias.x * TRUNK_BIAS_STR,
                        z:trunkDirBias.z * TRUNK_BIAS_STR};
                slope = INIT_SLOPE;
            }else{
                bias = {x:nodeFrom.dir.x * DIR_KEEP_BIAS,
                        z:nodeFrom.dir.z * DIR_KEEP_BIAS};
                slope = nodeFrom.slope;
            }
            var rndLen = Math.random(),
                rndArg = Math.random()*TAU;
            dir = {x: rndLen * Math.sin(rndArg) + bias.x,
                   z: rndLen * Math.cos(rndArg) + bias.z};
            var uvFix = 1/Math.sqrt(dir.x*dir.x + dir.z*dir.z);
            dir = {x:dir.x*uvFix, z:dir.z*uvFix};
            if(nodeFrom.dir === "up") trunkDirBias = dir;
            slope += MAX_D_SLOPE * (2*Math.random() - 1);
            if(slope > MAX_SLOPE) slope = MAX_SLOPE;
            if(slope < MIN_SLOPE) slope = MIN_SLOPE;
            var length = BRANCH_LEN * Math.random();
            nodeTo = {
                x: nodeFrom.x + length * Math.cos(slope) * dir.x,
                y: nodeFrom.y + length * Math.sin(slope),
                z: nodeFrom.z + length * Math.cos(slope) * dir.z,
                dir: dir, slope: slope, isEnd: true
            }
            //if(Math.abs(nodeTo.x)/maxX + nodeTo.y/maxY > 1) return;
            nodes.push(nodeTo);
            buds.push(nodeTo);
            branch = {from: nodeFrom, to: nodeTo, view: BRANCH_VIEW};
            branches.push(branch);
            renderBranch(branch);
        }// end if-is-trunk
    }// end for-tick
}//end func-grow

function rotateInit(){
    branches.sort(function(a,b){
        return (a.view.zIndex-b.view.zIndex);
    });
    interval = setInterval(rotate, ROTATE_MSPF);
}

var time = 0;
var view = {x:1, z:0}
function rotate(){
    time++;
    view = {x: Math.cos(time * ROTATE_RPF),
            z: Math.sin(time * ROTATE_RPF)};
    c.fillStyle = "white"
    c.fillRect(-maxX, 0, 2*maxX, maxY);
    branches.forEach(renderBranch);
    c.stroke();
    c.beginPath();
}

var prevView = null;
function renderBranch(branch){
    if(branch.view !== prevView){
        c.stroke();
        for(k in branch.view) c[k] = branch.view[k];
        c.beginPath();
        prevView = branch.view;
    }
    c.moveTo(view.x * branch.from.x + view.z * branch.from.z,
             branch.from.y);
    c.lineTo(view.x * branch.to.x + view.z * branch.to.z,
             branch.to.y);
}

2
Saya tahu karena jawaban ini hanya memiliki satu komentar: karena itu membuat orang terdiam.
Caridorc

49

Pesta

Output sampel:

ASCII Xmas tree

Ukuran pohon (yaitu jumlah garis) dilewatkan pada baris perintah, dan terbatas pada nilai 5 atau lebih besar. Gambar di atas dihasilkan dari perintah ./xmastree.sh 12. Berikut kode sumbernya:

#!/bin/bash
declare -a a=('.' '~' "'" 'O' "'" '~' '.' '*')
[[ $# = 0 ]] && s=9 || s=$1
[[ $s -gt 5 ]] || s=5
for (( w=1, r=7, n=1; n<=$s; n++ )) ; do
  for (( i=$s-n; i>0; i-- )) ;  do
    echo -n " "
  done
  for (( i=1; i<=w; i++ )) ; do
    echo -n "${a[r]}"
    [[ $r -gt 5 ]] && r=0 || r=$r+1
  done
  w=$w+2
  echo " "
done;
echo " "

Itu sangat cantik.
pandubear

42

Penafian: ini berdasarkan pohon natal LaTeX saya, pertama kali diposting di sini: https://tex.stackexchange.com/a/87921/8463

Kode berikut akan menghasilkan pohon chrismtas, dengan dekorasi acak. Anda dapat mengubah ukuran pohon, dan benih acak untuk menghasilkan pohon yang berbeda.

Untuk mengubah seed, modifikasi nilai di dalam \pgfmathsetseed{\year * 6}ke nilai numerik lainnya (yang default akan menghasilkan pohon baru setiap tahun)

Untuk mengubah ukuran pohon modifikasi order=10menjadi lebih besar, atau lebih kecil tergantung pada ukuran pohon yang Anda inginkan.

Contohnya. order=11:

masukkan deskripsi gambar di sini

order=8

masukkan deskripsi gambar di sini

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc, lindenmayersystems,shapes,decorations,decorations.shapes}
\begin{document}

\def\pointlistleft{}
\def\pointlistright{}
\pgfmathsetseed{\year * 6}

\makeatletter
\pgfdeclarelindenmayersystem{Christmas tree}{
    \symbol{C}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistleft\expandafter{\expandafter{\t}}}
    \symbol{c}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistright\expandafter{\expandafter{\t}}}
    \rule{S -> [+++G][---g]TS}
    \rule{G -> +H[-G]CL}
    \rule{H -> -G[+H]CL}
    \rule{g -> +h[-g]cL}
    \rule{h -> -g[+h]cL}
    \rule{T -> TL}
    \rule{L -> [-FFF][+FFF]F}
}
\makeatother

\begin{tikzpicture}[rotate=90]
\draw [color=green!50!black,l-system={Christmas tree,step=4pt,angle=16,axiom=LLLLLLSLFFF,order=10,randomize angle percent=20}] lindenmayer system -- cycle;

\pgfmathdeclarerandomlist{pointsleft}{\pointlistleft}
\pgfmathdeclarerandomlist{pointsright}{\pointlistright}
\pgfmathdeclarerandomlist{colors}{{red}{blue}{yellow}}

\foreach \i in {0,1,...,5}
{
    \pgfmathrandomitem{\c}{pointsleft}
    \pgfsettransform{\c}
    \pgfgettransformentries{\a}{\b}{\c}{\d}{\xx}{\yy}
    \pgfmathrandomitem{\c}{pointsright}
    \pgfsettransform{\c}
    \pgfgettransformentries{\a}{\b}{\c}{\d}{\XX}{\YY}
    \pgftransformreset

    \pgfmathsetmacro\calcy{min(\yy,\YY)-max((abs(\yy-\YY))/3,25pt)}

    \draw[draw=orange!50!black, fill=orange!50, decorate, decoration={shape backgrounds, shape=star, shape sep=3pt, shape size=4pt}, star points=5] (\xx,\yy) .. controls (\xx,\calcy pt) and (\XX,\calcy pt) .. (\XX,\YY);
}

\foreach \i in {0,1,...,15}
{
    \pgfmathrandomitem{\c}{pointsleft}
    \pgfsettransform{\c}
    \pgftransformresetnontranslations
    \draw[color=black] (0,0) -- (0,-4pt);
    \pgfmathrandomitem{\c}{colors}
    \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt];
}

\foreach \i in {0,1,...,15}
{
    \pgfmathrandomitem{\c}{pointsright}
    \pgfsettransform{\c}
    \pgftransformresetnontranslations
    \draw[color=black] (0,0) -- (0,-4pt);
    \pgfmathrandomitem{\c}{colors}
    \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt];
}

\end{tikzpicture}
\end{document}

Saya akan mengatakan bahwa ini didasarkan pada pohon Stefan Kottwitz, pertama kali diposting di sini . Mengatakan itu didasarkan pada pohon Anda membuatnya tampak seperti Anda menulis semua kode untuk itu, yang tidak benar. Orang lain menulis sebagian besar kode untuk pohon aktual.
The Guy with The Hat

@RyanCarlson ide untuk menggunakan sistem lindenmayer sebagai dasar untuk meletakkan dekorasi adalah ide saya, dan jika Anda memeriksa dengan hati-hati kedua kode yang Anda lihat, bahwa bagian lindenmayer dari kode tersebut dirancang ulang untuk juga memiliki bagian tambahan (seperti root untuk pohon, yang tidak memiliki aslinya). Selain itu saya tidak lupa untuk referensi aslinya, di mana siapa pun dapat memeriksa referensi (termasuk yang ke Peitgen dan Saupe, yang mungkin menjadi orang pertama yang menyusun persamaan pohon)
SztupY

34

Jalak 93

Ini adalah pohon yang tidak didekorasi:

&::00p20pv
vp010    <
v              p00<
>:0`!#v_" ",1-
v,"/"$<
>10g:2+v
vp01   <
>:0`!#v_" ",1-
v,"\"$<
>91+,00g1-::0`!#v_^
v        *2+1g02<
>:0`!#v_"-",1-
v g02$<
>91+,v
v    <
>:0`!#v_" ",1-
"||"$ <@,,

Output sampel, input adalah 10:

          /\
         /  \
        /    \
       /      \
      /        \
     /          \
    /            \
   /              \
  /                \
 /                  \
----------------------
          ||

Mari tambahkan beberapa dekorasi:

&::00p20pv
vp010    <
v              p00<
>:0`!#v_" ",1-
v,"/"$<
>10g:2+v             >"O" v
vp01   <            >?v
>:0`!#v_           >?>>" ">,1-
v,"\"$<             >?<
>91+,00g1-::0`!#v_^  >"*" ^
v        *2+1g02<
>:0`!#v_"-",1-
v g02$<
>91+,v
v    <
>:0`!#v_" ",1-
"||"$ <@,,

Output sampel:

          /\
         /O \
        /    \
       /   ** \
      /     *  \
     /    **   O\
    /* O* *  *   \
   / O      O     \
  / *  **   O*     \
 /   *OO   *  OOO * \
----------------------
          ||

32

HTML dan CSS

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Scalable christmas tree</title>
<style>
body {
  background-color: skyblue;
  background-size: 11px 11px, 21px 21px, 31px 31px;
  background-image: radial-gradient(circle at 5px 5px,white,rgba(255,255,255,0) 1px), radial-gradient(circle at 5px 5px,white,rgba(255,255,255,0) 2px), radial-gradient(circle at 5px 5px,white 1px,skyblue 1px);
}
div {
  float: left;
  border-style: solid;
  border-color: transparent;
  border-bottom-color: green;
  border-width: 20px;
  border-top-width: 0;
  border-bottom-width: 30px;
  border-bottom-left-radius: 35%;
  border-bottom-right-radius: 35%;
  box-shadow: red 0 15px 5px -13px;
  animation-name: light;
  animation-duration: 1s;
  animation-direction: alternate;
  animation-iteration-count: infinite;
  -webkit-animation-name: light;
  -webkit-animation-duration: 1s;
  -webkit-animation-direction: alternate;
  -webkit-animation-iteration-count: infinite;
}
section {
  float: left;
}
header {
  color: yellow;
  font-size: 30px;
  text-align: center;
  text-shadow: red 0 0 10px;
  line-height: .5;
  margin-top: 10px;
  animation-name: star;
  animation-duration: 1.5s;
  animation-direction: alternate;
  animation-iteration-count: infinite;
  -webkit-animation-name: star;
  -webkit-animation-duration: 1.5s;
  -webkit-animation-direction: alternate;
  -webkit-animation-iteration-count: infinite;
}
footer {
  float: left;
  width: 100%;
  height: 20px;
  background-image: linear-gradient(to right, transparent 45%, brown 45%, #600 48%, #600 52%, brown 55%, transparent 55%);
}
:target {
  display: none;
}
@keyframes star {
  from { text-shadow: red 0 0 3px; }
  to { text-shadow: red 0 0 30px; }
}
@-webkit-keyframes star {
  from { text-shadow: red 0 0 3px; }
  to { text-shadow: red 0 0 30px; }
}
@keyframes light {
  from { box-shadow: red 0 15px 5px -13px; }
  to { box-shadow: blue 0 15px 5px -13px; }
}
@-webkit-keyframes light {
  from { box-shadow: red 0 15px 5px -13px; }
  to { box-shadow: blue 0 15px 5px -13px; }
}
</style>
</head>
<body>
<section>
<header>&#x2605;</header>
<div id="0"><div id="1"><div id="2"><div id="3"><div id="4"><div id="5"><div id="6"><div id="7"><div id="8"><div id="9"><div id="10"><div id="11"><div id="12"><div id="13"><div id="14"><div id="15"><div id="16"><div id="17"><div id="18"><div id="19"><div id="20"><div id="21"><div id="22"><div id="23"><div id="24">
</div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
<footer></footer>
</section>
</body>
</html>

Ukuran antara 1 dan 25 didukung - cukup tambahkan ukuran ke URL sebagai pengidentifikasi fragmen.

Bekerja di Chrome, Explorer dan Firefox. Di Opera jelek, tetapi bagian penskalaannya bekerja.

Akses sampel:

http://localhost/xmas.html#5

pohon natal ukuran 5

Akses sampel:

http://localhost/xmas.html#15

pohon natal ukuran 15

Tampilan langsung:

http://dabblet.com/gist/8026898

(Tampilan langsung tidak mengandung CSS yang diawali vendor dan menyertakan tautan untuk mengubah ukuran.)


1
+1 Saya suka ide :targetuntuk skala output :-)
squeamish ossifrage

32

Jawa

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 *
 * @author Quincunx
 */
public class ChristmasTree {
    public static double scale = 1.2;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ChristmasTree();
            }
        });
    }

    public ChristmasTree() {
        try {
            URL url = new URL("http://imgs.xkcd.com/comics/tree.png");
            BufferedImage img = ImageIO.read(url);

            JFrame frame = new JFrame();
            frame.setUndecorated(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

            BufferedImage result = 
                    new BufferedImage((int)(img.getWidth() * scale), 
                            (int) (img.getHeight() * scale), 
                            BufferedImage.TYPE_INT_RGB);
            Graphics2D g = (Graphics2D) result.getGraphics();
            g.drawRenderedImage(img, AffineTransform.getScaleInstance(scale, scale));

            JImage image = new JImage(result);
            image.setToolTipText("Not only is that terrible in general, but you "
                    + "just KNOW Billy's going to open the root present first, "
                    + "and then everyone will have to wait while the heap is "
                    + "rebuilt.");
            frame.add(image);
            frame.pack();
            frame.setVisible(true);

        } catch (IOException ex) {

        }
    }

    class JImage extends JPanel implements MouseListener {

        BufferedImage img;

        public JImage(){
            this(null);
        }
        public JImage(BufferedImage image){
            img = image;
            setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
            addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, WIDTH, WIDTH, this);
        }

        public void setImage(BufferedImage image) {
            img = image;
            repaint();
        }

        @Override
        public void mouseClicked(MouseEvent me) {
            System.exit(0);
        }

        @Override
        public void mousePressed(MouseEvent me) {

        }

        @Override
        public void mouseReleased(MouseEvent me) {

        }

        @Override
        public void mouseEntered(MouseEvent me) {

        }

        @Override
        public void mouseExited(MouseEvent me) {

        }
    }
}

Untuk mengubah ukuran, ubah scale ke beberapa nilai ganda lainnya (pertahankan sekitar 1 jika Anda ingin melihat sesuatu).

Contoh hasil (untuk skala 1.0, terlalu malas untuk mengambil tangkapan layar, jadi cukup poskan apa fungsinya):

masukkan deskripsi gambar di sini

Program ini mengambil gambar ini dari internet, mengubah ukurannya sesuai dengan scale, lalu meletakkannya di jendela yang tidak didekorasi dimana gambar itu ditampilkan. Mengklik pada jendela menutup program. Juga, teks tip alat ada di sana, tetapi tautannya tidak.


3
Ini bukan "menggambar" apa pun.
Mrchief

@Mrchief Tantangannya bukan untuk menggambar sesuatu; itu untuk membuat pohon. Ini membuat pohon, dengan mengambil gambar
Justin

2
Apakah Anda menghasilkan gambar sendiri? Tidak. Anda hanya mengunduhnya dari suatu tempat. Pertanyaannya bukan untuk mengunduh gambar dan mengubah ukurannya. Periksa jawaban lain dan Anda akan mengerti apa yang sebenarnya diminta OP.
Mrchief

10
@Mrchief Apakah Anda memperhatikan siapa yang menulis OP? Ini adalah salah satu dari banyak solusi yang mungkin saya cari ketika saya mengajukan pertanyaan ini.
Justin

3
Ha! Memukul kepala! Karena ini adalah posting Anda sendiri, saya tidak melihat banyak alasan untuk berdebat, selain menyatakan pendapat saya bahwa ini tidak sama dengan kode Anda "membuat" sesuatu (seperti yang dilakukan oleh sisa jawaban). Sama seperti mengunduh film tidak sama dengan membuat film.
Mrchief

28

TI-89 Basic

Hanya karena saya ingin melihat Pohon Natal di kalkulator saya. Saya akan mengetiknya di sini seperti yang muncul di kalkulator saya.

:tree()
:Prgm
:
:Local size
:Prompt size
:
:Local d,x,y,str,orn
:size→x
:0→y
:{" "," "," "," "," "," "," "," ","°","∫","θ","O","©"}→orn
:size→d
:
:While d≥0
: d-1→d
: ""→str
: 
: While x≥0
:  str&" "→str
:  x-1→x
: EndWhile
: 
: str&"/"→str
: 2*y→x
:
: While x>0
:  str&elementAt(orn,rand(colDim(list▶mat(orn))))→str
:  x-1→x
: EndWhile
: 
: str&"\"→str
: Disp str
: y+1→y
: d→x
:EndWhile
:
:""→str
:
:For x,1,2*(size+2)
: str&"-"→str
:EndFor
:Disp str
:
:""→str
:For x,1,size+1
: str&" "→str
:EndFor
:str&"||"→str
:Disp str
:
:EndPrgm


:elementAt(l,i)
:Func
:Local m
:list▶mat(l)→m
:
:Local cd
:colDim(m)→cd
:
:If i>cd or i≤0 Then
: 1/0
:Else
: If i=cd Then
:  Return sum(mat▶list(subMat(m,1,i))) - sum(mat▶list(subMat(m,1,i+1)))
: Else
:  Return sum(mat▶list(subMat(m,1,i))) - sum(mat▶list(subMat(m,1,i+1)))
: EndIf
:EndIf
:EndFunc

Ini bekerja dengan cara yang sama dengan jawaban Befunge saya, tetapi saya menggunakan ornamen yang berbeda. Ya, elementAtfungsi saya yang berulang kali memperlambat program karena banyak konversi antara daftar dan matriks, tetapi ketika saya menulisnya sebelumnya, saya memutuskan untuk tidak mengeditnya. Juga, saya belajar sambil mengetik jawaban ini yang ©membuat komentar (saya pikir itu terlihat seperti @, tetapi itu adalah karakter lain). Tidak pernah tahu apa itu sebelumnya.

Output sampel:

size?
7
        /\
       / O\
      /∫   \
     / ©  ∫°\
    / θ ∫   ∫\
   /°  °  ©  ©\
  /O  ∫  O °   \
 / θ  °©  ∫ O  θ\
------------------
        ||

Saya suka itu; mereka terlihat seperti tongkat permen.


Versi apa ini?
SuperJedi224

@ SuperJedi224 Saya menambahkannya ke jawaban
Justin

27

Bahasa Wolfram ( Mathematica )

Seperti yang dibahas di utas Reddit yang terkenal: t * sin (t) ≈ Pohon Natal

PD = .5; s[t_, f_] := t^.6 - f;
 dt[cl_, ps_, sg_, hf_, dp_, f_] := 
    {PointSize[ps], Hue[cl, 1, .6 + sg .4 Sin[hf s[t, f]]], 
     Point[{-sg s[t, f] Sin[s[t, f]], -sg s[t, f] Cos[s[t, f]], dp + s[t, f]}]};

 frames = ParallelTable[

    Graphics3D[Table[{dt[1, .01, -1, 1, 0, f], dt[.45, .01, 1, 1, 0, f], 
                      dt[1, .005, -1, 4, .2, f], dt[.45, .005, 1, 4, .2, f]}, 
 {t, 0, 200, PD}],

     ViewPoint -> Left, BoxRatios -> {1, 1, 1.3}, ViewVertical -> {0, 0, -1}, 
    ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}}, Boxed -> False, Lighting -> "Neutral", 
    PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}}, Background -> Black],

   {f, 0, 1, .01}];

Export["tree.gif", frames]

masukkan deskripsi gambar di sini


Di mana Anda mengatur ukuran dan bagaimana pengaruhnya terhadap pohon yang dihasilkan?
manatwork

2
@manatwork ini pada dasarnya grafik t*sin(t)seperti yang saya katakan di posting. Jadi merencanakan untuk t yang lebih besar hanya akan membuat pohon yang lebih besar:Table[..., {t, 0, 200, PD}]
Vitaliy Kaurov

24

Bash dengan Bc dan ImageMagick

#!/bin/bash

size="${1:-10}"

width=$(( size*25 ))
height=$(( size*size+size*10 ))

cos=( $( bc -l <<< "for (i=0;i<3.14*2;i+=.05) c(i)*100" ) )
sin=( $( bc -l <<< "for (i=0;i<3.14*2;i+=.05) s(i)*100" ) )
cos=( "${cos[@]%.*}" )
sin=( "${sin[@]%.*}" )

cos=( "${cos[@]/%-/0}" )
sin=( "${sin[@]/%-/0}" )

snow=()
needle=()
decor=()
for ((i=2;i<size+2;i++)); do
  for ((j=3;j<=31;j++)); do
    (( x=width/2+i*10+cos[62-j]*i*10/100 ))
    (( y=i*i+sin[j]*i*5/100 ))

    for ((e=0;e<i;e++)); do
      needle+=(
        -draw "line $x,$y $(( x+RANDOM%i-i/2 )),$(( y+RANDOM%i-i/2 ))"
        -draw "line $(( width-x )),$y $(( width-x+RANDOM%i-i/2 )),$(( y+RANDOM%i-i/2 ))"
      )
    done

    (( RANDOM%2 )) && (( x=width-x ))
    snow+=(
      -draw "circle $x,$(( y-i/2 )) $(( x+i/3 )),$(( y-i/2+i/3 ))"
    )

    (( RANDOM%10 )) || decor+=(
      -fill "rgb($(( RANDOM%5*20+50 )),$(( RANDOM%5*20+50 )),$(( RANDOM%5*20+50 )))"
      -draw "circle $x,$(( y+i )) $(( x+i/2 )),$(( y+i+i/2 ))"
    )
  done
done

flake=()
for ((i=0;i<width*height/100;i++)); do
  flake+=(
    -draw "point $(( RANDOM%width )),$(( RANDOM%height ))"
  )
done

convert \
  -size "${width}x$height" \
  xc:skyblue \
  -stroke white \
  -fill white \
  "${snow[@]}" \
  -blur 5x5 \
  "${flake[@]}" \
  -stroke brown \
  -fill brown \
  -draw "polygon $(( width/2 )),0 $(( width/2-size )),$height, $(( width/2+size )),$height" \
  -stroke green \
  -fill none \
  "${needle[@]}" \
  -stroke none \
  -fill red \
  "${decor[@]}" \
  x:

Contoh dijalankan:

bash-4.1$ ./xmas.sh 5

Output sampel:

pohon natal ukuran 5

Contoh dijalankan:

bash-4.1$ ./xmas.sh 15

Output sampel:

pohon natal ukuran 15


23

C

Output sampel untuk kedalaman = 4, zoom = 2.0

Pohon

Jawaban ini menggunakan pendekatan yang sangat berbeda dari jawaban lainnya. Ini menghasilkan struktur pohon dengan percabangan rekursif. Setiap cabang diwakili oleh satu set lingkaran. Dan akhirnya fungsi utama sampel lingkaran dan isi dengan karakter ketika lingkaran bertemu. Karena dilakukan dengan mengambil sampel adegan (seperti ray-tracing), maka secara intrinsik skalabel. Downside adalah kecepatan, karena melintasi seluruh struktur pohon untuk setiap "pixel"!

Argumen baris perintah pertama mengontrol kedalaman percabangan. Dan skala kontrol kedua (2 berarti 200%).

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

#define PI 3.14159265359

float sx, sy;

float sdCircle(float px, float py, float r) {
    float dx = px - sx, dy = py - sy;
    return sqrtf(dx * dx + dy * dy) - r;
}

float opUnion(float d1, float d2) {
    return d1 < d2 ? d1 : d2;
}

#define T px + scale * r * cosf(theta), py + scale * r * sin(theta)

float f(float px, float py, float theta, float scale, int n) {
    float d = 0.0f;
    for (float r = 0.0f; r < 0.8f; r += 0.02f)
        d = opUnion(d, sdCircle(T, 0.05f * scale * (0.95f - r)));

    if (n > 0)
        for (int t = -1; t <= 1; t += 2) {
            float tt = theta + t * 1.8f;
            float ss = scale * 0.9f;
            for (float r = 0.2f; r < 0.8f; r += 0.1f) {
                d = opUnion(d, f(T, tt, ss * 0.5f, n - 1));
                ss *= 0.8f;
            }
        }

    return d;
}

int ribbon() {
    float x = (fmodf(sy, 0.1f) / 0.1f - 0.5f) * 0.5f;
    return sx >= x - 0.05f && sx <= x + 0.05f;
}

int main(int argc, char* argv[]) {
    int n = argc > 1 ? atoi(argv[1]) : 3;
    float zoom = argc > 2 ? atof(argv[2]) : 1.0f;
    for (sy = 0.8f; sy > 0.0f; sy -= 0.02f / zoom, putchar('\n'))
        for (sx = -0.35f; sx < 0.35f; sx += 0.01f / zoom) {
            if (f(0, 0, PI * 0.5f, 1.0f, n) < 0.0f) {
                if (sy < 0.1f)
                    putchar('.');
                else {
                    if (ribbon())
                        putchar('=');
                    else
                        putchar("............................#j&o"[rand() % 32]);
                }
            }
            else
                putchar(' ');
        }
}

2
Saya pikir aman untuk mengatakan ini adalah jawaban yang paling mengesankan secara teknis untuk pertanyaan ini sejauh ini.
Stuntddude

20

Mathematica ASCII

Saya sangat suka seni ASCII, jadi saya menambahkan jawaban yang sangat berbeda - terutama begitu singkat di Mathematica:

Column[Table[Row[RandomChoice[{"+", ".", "*", "~", "^", "o"}, k]], {k, 1, 35, 2}], 
Alignment -> Center]

masukkan deskripsi gambar di sini

Dan sekarang dengan sedikit kecanggihan, pohon ASCII dinamis yang dapat diskalakan. Perhatikan dengan seksama - pohon juga berubah - salju menempel ke cabang kemudian jatuh ;-)

DynamicModule[{atoms, tree, pos, snow, p = .8, sz = 15},

 atoms = {
   Style["+", White],
   Style["*", White],
   Style["o", White],
   Style[".", Green],
   Style["~", Green],
   Style["^", Green],
   Style["^", Green]
   };

 pos = Flatten[Table[{m, n}, {m, 18}, {n, 2 m - 1}], 1];

 tree = Table[RandomChoice[atoms, k], {k, 1, 35, 2}];

 snow = Table[
   RotateLeft[ArrayPad[{RandomChoice[atoms[[1 ;; 2]]]}, {0, sz}, " "],
     RandomInteger[sz]], {sz + 1}];

 Dynamic[Refresh[

   Overlay[{

     tree[[Sequence @@ RandomChoice[pos]]] = RandomChoice[atoms];
     Column[Row /@ tree, Alignment -> Center, Background -> Black],

     Grid[
      snow = 
       RotateRight[
        RotateLeft[#, 
           RandomChoice[{(1 - p)/2, p, (1 - p)/2} -> {-1, 0, 1}]] & /@
          snow
        , {1, 0}]]

     }, Alignment -> Center]

   , UpdateInterval -> 0, TrackedSymbols -> {}]
  ]
 ]

masukkan deskripsi gambar di sini


Bagus Di mana Anda menyesuaikan ukurannya? Apakah itu Tableparameter 35 in ?
manatwork

@manatwork ya 35 di Tabel. Terima kasih;)
Vitaliy Kaurov

19

Saya membuat ini untuk tantangan pada / r / dailyprogrammer , (tidak yakin apakah menggunakan kembali kode bertentangan dengan semangat / aturan ini) tetapi:

Brainfuck. Dibawa sebagai input nomor (panjang baris bawah daun) dan dua karakter. Satu ruang antara masing-masing.

Contoh input: 13 = +

Contoh output:

      +
     +++
    +++++
   +++++++
  +++++++++
 +++++++++++
+++++++++++++
     ===

Kode:

                   >
                  ,--
                 -----
                -------
               ---------
              ---------[+
             +++++++++++++
            +++++++++++++++
           +++<[>>++++++++++
          <<-]>--------------
         ---------------------
        -------------[<+>-]>[<<
       +>>-]<,------------------
      --------------],>,,>>++++[<
     ++++++++>-]++++++++++>+<<<<<-
    [>>>>>>+>+<<<<<<<--]>>>>>>>[<<<
   <<<<++>>>>>>>-]<<<<<<<[>>>>>>[<<<
  .>>>>+<-]>[<+>-]<<[<<<.>>>>>+<<-]>>
 [<<+>>-]<<<.>>><-<++<<<<<--]>>...>>>-
--[>+<<<<..>>>--]<.>>[<<<.>>>>+<-]<<<<<
                ...>>>.

1
Akhirnya, jawaban brainfuck!
Pharap

16

Pengolahan

Pohon Natal fraktal asli. Posisi Mouse Y menentukan ukuran, gunakan tombol panah atas dan bawah untuk mengubah jumlah generasi.

int size = 500;

int depth = 10;

void setup() {
  frameRate(30);
  size(size, size, P2D);
}

void draw() {
  background(255);
  tree(size/2.0, size, 0.0, radians(0), radians(108), (size - mouseY)/3, depth);
  tree(size/2.0, size, 0.0, radians(108), radians(0), (size - mouseY)/3, depth);
}

void keyPressed() {
  if(keyCode == UP) depth++;
  if(keyCode == DOWN) depth--;
  depth = max(depth, 1);
}

void tree(float posX, float posY, float angle, float forkRight, float forkLeft, float length, int generation) {
  if (generation > 0) {
    float nextX = posX + length * sin(angle);
    float nextY = posY - length * cos(angle);

    line(posX, posY, nextX, nextY);

    tree(nextX, nextY, angle + forkRight, forkRight, forkLeft, length*0.6, generation - 1);
    tree(nextX, nextY, angle - forkLeft,  forkRight, forkLeft, length*0.6, generation - 1);
  }
}

Pohon Natal yang indah, bukan begitu, bu?

Or, if you prefer a fuller tree:

int size = 500;

int depth = 10;

void setup() {
  frameRate(30);
  size(size, size, P2D);
}

void draw() {
  background(255);
  tree(size/2.0 - 5, size, 0.0, 0.0, (size - mouseY)/3, depth);
}

void keyPressed() {
  if(keyCode == UP) depth++;
  if(keyCode == DOWN) depth--;
  depth = max(depth, 1);
}

void tree(float posX, float posY, float angle, float fork, float length, int generation) {
  if (generation > 0) {
    float nextX = posX + length * sin(angle);
    float nextY = posY - length * cos(angle);

    line(posX, posY, nextX, nextY);

    tree(nextX, nextY, angle + fork + radians(108), fork, length*0.6, generation - 1);
    tree(nextX, nextY, angle - fork,                fork, length*0.6, generation - 1);
    tree(nextX, nextY, angle + fork - radians(108), fork, length*0.6, generation - 1);
  }
}

Saya sangat kecewa bahwa seseorang mengalahkan saya untuk memposting pohon fraktal meskipun saya berada di depan mereka dalam ide dan benar-benar mulai mengerjakannya: /


14

Rubi

((1..20).to_a+[6]*4).map{|i|puts ('*'*i*2).center(80)}

Selamat Tahun Baru

Anda dapat menyesuaikan output dengan mengubah *.
Untuk pohon hijau:((1..20).to_a+[6]*4).map{|i|puts "\e[32m"+('*'*i*2).center(80)}

Approach 2 (Pohon Natal yang tidak terlihat seperti panah)

((1..6).to_a+(3..9).to_a+(6..12).to_a+[3]*4).map{|i|puts "\e[32m"+('*'*i*4).center(80)}

Selamat Tahun Baru

Pendekatan 3

((1..20).to_a+[6]*4).map{|i|puts' '*(20-i)+'*'*(2*i-1)}

2
Ini lebih panah, lalu pohon natal!
klingt.net

4
@ klingt.net * dari.
NARKOZ

Saatnya menyalakan pohon natal.
NARKOZ

Dan di mana Anda menentukan ukurannya?
manatwork

@manatwork dalam rentang. 1..20,, 1..6dll.
NARKOZ

14

Turtle Graphics

masukkan deskripsi gambar di sini

Berdasarkan sifat-sifat spiral Euler .

Kode:

masukkan deskripsi gambar di sini

Skala ditentukan oleh ukuran langkah ( move forward by: 6). Versi interaktif tersedia di sini .

PS Terinspirasi oleh pertanyaan ini .


Di mana "terukur" ini? Selain itu, ini luar biasa!
Justin

@ Quincunx Anda dapat mengubah skala dengan mengubah move forward by 6. Misalnya, 10akan menghasilkan pohon yang lebih besar. Sebenarnya tidak ada input dalam "bahasa" ini (atau seluruh kode dapat diperlakukan sebagai input;)).
ybeltukov

14

Pengolahan

Saya membuat generator pohon ini menggunakan L-System dan Turtle.

Pohon

kode:

//My code, made from scratch:
final int THE_ITERATIONS = 7;
final float SCALE = 1;
final int ANGLE = 130;
final int SIZE = 4;

final int ITERATIONS = THE_ITERATIONS - 1;

int lineLength;

String lSystem;
ArrayList<Turtle> turtles;

int turtleIndex;
int lSystemIndex;

void setup()
{
  size(320, 420);
  background(255);
  translate(width / 2, height - 70);

  lineLength = ITERATIONS * 2 + 2;

  lSystem = "[-F][+F]F";

  turtles = new ArrayList<Turtle>(ITERATIONS + 1);
  lSystemIndex = 0;

  calculateLSystem();
  println(lSystem);

  turtles.add(new Turtle(0, 0));

  doTurtles();
  save("Tree.png");
}

void doTurtles()
{
  while(lSystemIndex < lSystem.length())
  {
    print("\"" + lSystem.charAt(lSystemIndex) + "\": ");
    if(lSystem.charAt(lSystemIndex) == 'F')
    {
      turtleForward();
    }
    else if(lSystem.charAt(lSystemIndex) == '[')
    {
      lineLength -= 2;
      addTurtle();
      println(turtles.size());
    }
    else if(lSystem.charAt(lSystemIndex) == ']')
    {
      lineLength += 2;
      removeTurtle();
      println(turtles.size());
    }
    else if(lSystem.charAt(lSystemIndex) == '+')
    {
      turtleRight();
    }
    else if(lSystem.charAt(lSystemIndex) == '-')
    {
      turtleLeft();
    }
    lSystemIndex++;
  }
}

void addTurtle()
{
  turtles.add(new Turtle(turtles.get(turtles.size() - 1)));
}

void removeTurtle()
{
  turtles.remove(turtles.size() - 1);
}

void turtleLeft()
{
  turtles.get(turtles.size() - 1).left(ANGLE + random(-5, 5));
}

void turtleRight()
{
  turtles.get(turtles.size() - 1).right(ANGLE + random(-5, 5));
}

void turtleForward()
{
  print(turtles.get(turtles.size() - 1) + ": ");
  strokeWeight(min(lineLength / SIZE, 1));
  stroke(5 + random(16), 90 + random(16), 15 + random(16));
  if(turtles.size() == 1)
  {
    strokeWeight(lineLength / 2);
    stroke(100, 75, 25);
  }
  turtles.get(turtles.size() - 1).right(random(-3, 3));
  turtles.get(turtles.size() - 1).forward(lineLength);
}

void calculateLSystem()
{
  for(int i = 0; i < ITERATIONS; i++)
  {
    lSystem = lSystem.replaceAll("F", "F[-F][+F][F]");
  }
  lSystem = "FF" + lSystem;
}

void draw()
{

}

//——————————————————————————————————————————————————————
// Turtle code, heavily based on code by Jamie Matthews
// http://j4mie.org/blog/simple-turtle-for-processing/
//——————————————————————————————————————————————————————

class Turtle {
  float x, y; // Current position of the turtle
  float angle = -90; // Current heading of the turtle
  boolean penDown = true; // Is pen down?
  int lineLength;

  // Set up initial position
  Turtle (float xin, float yin) {
    x = xin;
    y = yin;
    //lineLength = lineLengthin;
  }

  Turtle (Turtle turtle) {
    x = turtle.x;
    y = turtle.y;
    angle = turtle.angle;
    //lineLength = turtle.lineLength - 1;
  }

  // Move forward by the specified distance
  void forward (float distance) {
    distance = distance * SIZE * random(0.9, 1.1);
    // Calculate the new position
    float xtarget = x+cos(radians(angle)) * distance;
    float ytarget = y+sin(radians(angle)) * distance;

    // If the pen is down, draw a line to the new position
    if (penDown) line(x, y, xtarget, ytarget);
    println(x + ", " + y + ", " + xtarget + ", " + ytarget);
    // Update position
    x = xtarget;
    y = ytarget;
  }

  // Turn left by given angle
  void left (float turnangle) {
    angle -= turnangle;
    println(angle);
  }

  // Turn right by given angle
  void right (float turnangle) {
    angle += turnangle;
    println(angle);
  }
}

2
Iya! Sistem-L!
luser droog

1
Saya setuju tentang hal itu menjadi yang paling realistis :)
Timtech

@Timtech saya tidak setuju. Saya pikir ini adalah yang paling realistis kedua, setelah jawaban Javascript Jan Dvorak . Maksudku, lihat jarum-jarum itu (yang ini)! Mereka semua berkumpul dalam pola yang belum pernah saya lihat di pohon hijau. Namun, pohon Jan terlihat sangat mirip pohon cemara bagiku.
Justin

1
@ Quincunx Aku pasti melewatkan yang itu. Tetap saja, yang ini terlihat cukup bagus.
Timtech

@Quincunx Pohon Jan — dan Howard juga — benar-benar keren, tetapi belum tentu sepenuhnya realistis . Jan bahkan mengakui bahwa pohon itu hanya "quasirealistic". - RyanCarlson 10 detik yang lalu
The Guy with The Hat

12

JavaScript (dijalankan di halaman mana saja di konsol)

Saya bermain golf ini tetapi kemudian memutuskan untuk tidak melakukannya, jadi seperti yang Anda lihat ada BANYAK angka ajaib: P

// size
s = 300

document.write('<canvas id=c width=' + s + ' height=' + s + '>')
c = document.getElementById('c').getContext('2d')
c.fillStyle = '#0D0'
for (var i = s / 3; i <= s / 3 * 2; i += s / 6) {
  c.moveTo(s / 2, s / 10)
  c.lineTo(s / 3, i)
  c.lineTo(s / 3 * 2, i)
  c.fill()
}
c.fillStyle = '#DA0'
c.fillRect(s / 2 - s / 20, s / 3 * 2, s / 10, s / 6)

Hasil untuk s = 300:

tangkapan layar

s = 600:

tangkapan layar


2
Apakah Anda akan menghias pohon itu? :-)
Justin

1
@Quincunx Mungkin, saya dapat bekerja pada nanti :)
Doorknob

2
GAH! Di mana titik koma ?!
Andrew Larsson


10

Bahasa Game Maker

spr_tree

spr_tree

Buat Acara Pohon

image_speed=0
size=get_integer("How big do you want me to be?#Integer between 1 and 10, please!",10)
image_index=size-1

Kamar, 402 x 599

Pohon itu ditempatkan di (0,0)

Bonus! Anda dapat mengubah ukuran pohon Natal setelah input awal dengan tombol 0-9.


8

AppleScript + SE Answer

Sebenarnya mengambil ini secara tidak sengaja saat mengedit jawaban dalam pertanyaan ini. Sosok pergi.

Gunakan ini dengan menjalankan kode, ketikkan nomor yang Anda inginkan, geser ke pos SE dan klik di bidang teks. Ini mengeksploitasi fakta yang mengutip tumpukan.

tell application "System Events"
    set layers to (display dialog "" default answer "")'s text returned as number
    delay 5
    repeat layers times
        keystroke ">"
    end repeat
end tell

Output (input 50):

>


6

Pohon FORTRAN dihiasi

    character(len=36) :: f='/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\'
    character(len=18) :: g = '                  '
    character(len=14) :: p = ".x$.+oO+oO.#,~"
    character(len=10) :: q

    n = iargc()
    if (n /= 1) then 
        k = len(g)
    else
        call getarg(1,q) 
        read(q,*) k
    end if
    l = modulo(k,len(g))+1
    do i=1,l
        j = mod(i,len(p)-1)+1
        print *,g(1:l-i),p(j:j),f(1:2*i),p(j+1:J+1)
        end do
    print *,g(1:l-1),f(1:4)
    end

Pohon itu memiliki kisaran ukuran yang terbatas, tetapi ia percaya pohon itu secara akurat mencerminkan kehidupan sebagian besar pohon Natal.

Dari pohon bayi:

$./tree
 x/\$
 /\/\

Ke pohon remaja:

$./tree 6
       x/\$
      $/\/\.
     ./\/\/\+
    +/\/\/\/\o
   o/\/\/\/\/\O
  O/\/\/\/\/\/\+
 +/\/\/\/\/\/\/\o
       /\/\

Untuk dewasa:

$./tree 17
                  x/\$
                 $/\/\.
                ./\/\/\+
               +/\/\/\/\o
              o/\/\/\/\/\O
             O/\/\/\/\/\/\+
            +/\/\/\/\/\/\/\o
           o/\/\/\/\/\/\/\/\O
          O/\/\/\/\/\/\/\/\/\.
         ./\/\/\/\/\/\/\/\/\/\#
        #/\/\/\/\/\/\/\/\/\/\/\,
       ,/\/\/\/\/\/\/\/\/\/\/\/\~
      ./\/\/\/\/\/\/\/\/\/\/\/\/\x
     x/\/\/\/\/\/\/\/\/\/\/\/\/\/\$
    $/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\.
   ./\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\+
  +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\o
 o/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\O
                  /\/\    

5

Jawa

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.imageio.ImageIO;


public class ChristmasTree {
    static class Point{
        Point(int a,int b){x=a;y=b;}
        int x,y;
        double distance(Point o){
            int dx=x-o.x;
            int dy=y-o.y;
            return Math.sqrt(dx*dx+dy*dy);
        }
    }
    static int siz;
    static BufferedImage b;
    static Random r=new Random();
    public static void main(String[]args) throws IOException{

        if(args.length==0){
            siz=(new Scanner(System.in)).nextInt();
        }else{
            siz=Integer.parseInt(args[0]);
        }
        b=new BufferedImage(20*siz,30*siz,BufferedImage.TYPE_INT_RGB);
        Graphics2D g=(Graphics2D)b.getGraphics();
        g.setColor(new Color(140,70,20));
        int h=b.getHeight();h*=0.4;
        for(int i=(int)(0.4*b.getWidth());i<(int)(0.6*b.getWidth());i++){
            if(r.nextDouble()<0.3){
                g.drawLine(i,b.getHeight(),i+r.nextInt(2)-1,h);
            }
        }
        for(int i=h;i<b.getHeight();i++){
            if(r.nextDouble()<0.3){
                g.drawLine((int)(0.4*b.getWidth()),i,(int)(0.6*b.getWidth()),i);
            }
        }
        for(int i=0;i<siz;i++){
            g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
            g.drawLine(b.getWidth()/2-(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9)+r.nextInt(5)-2,b.getWidth()/2+(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9)+r.nextInt(5)-2);
            g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
            g.drawLine(b.getWidth()/2-(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9),b.getWidth()/2,(int)(b.getHeight()*(0.1+(.06*i)/siz)));
            g.setColor(new Color(r.nextInt(4),150+r.nextInt(15),20+r.nextInt(7)));
            g.drawLine(b.getWidth()/2+(int)(b.getWidth()*0.42*i/siz),(int)(b.getHeight()*0.9),b.getWidth()/2,(int)(b.getHeight()*(0.1+(.06*i)/siz)));
        }
        g.setColor(new Color(150,120,40));
        g.fillOval((b.getWidth()-siz-2)/2,b.getHeight()/10,siz+2,siz+2);
        g.setColor(new Color(250,240,80));
        g.fillOval((b.getWidth()-siz)/2,b.getHeight()/10,siz,siz);
        List<Color>c=Arrays.asList(new Color(0,255,0),new Color(255,0,0),new Color(130,0,100),new Color(0,0,200),new Color(110,0,200),new Color(200,205,210),new Color(0,240,255),new Color(255,100,0));
        List<Point>pts=new ArrayList<>();
        pts.add(new Point((b.getWidth()-siz)/2,b.getHeight()/10));
        loop:for(int i=0;i<8+siz/4;i++){
            int y=r.nextInt((8*b.getHeight())/11);
            int x=1+(int)(b.getWidth()*0.35*y/((8*b.getHeight())/11));
            x=r.nextInt(2*x)-x+b.getWidth()/2;
            y+=b.getHeight()/8;
            g.setColor(c.get(r.nextInt(c.size())));
            x-=siz/2;
            Point p=new Point(x,y);
            for(Point q:pts){
                if(q.distance(p)<1+2*siz)continue loop;
            }
            pts.add(p);
            g.fillOval(x,y,siz,siz);
        }
        ImageIO.write(b,"png",new File("tree.png"));
    }
}

Hasil sampel:

Ukuran = 3:

masukkan deskripsi gambar di sini

Ukuran = 4:

masukkan deskripsi gambar di sini

Ukuran = 5:

masukkan deskripsi gambar di sini

Ukuran = 12:

masukkan deskripsi gambar di sini

Ukuran = 20:

masukkan deskripsi gambar di sini


1
Saya tidak memperhatikan ini sebelumnya. +1 sangat keren
spaghetto

4

Rebol

Dengan dialek untuk menampilkan simbol. Untuk mengubah ukuran pohon, cukup ubah parameter make-tree.

make-tree: func [int /local tr] [
  tr: copy []
  length: (int * 2) + 3
  repeat i int [
      repeat j 3 [
            ast: to-integer ((i * 2) - 1 + (j * 2) - 2)
            sp: to-integer (length - ast) / 2
            append/dup tr space sp 
            append/dup tr "*" ast 
            append tr lf
      ]
  ]
  append/dup tr space (length - 1) / 2
  append tr "|"
  append tr lf
  tr
]

print make-tree 3

pohon dengan 3 lapisan pohon dengan 5 lapisan


3
Di mana Anda mengatur ukuran dan bagaimana pengaruhnya terhadap pohon yang dihasilkan?
manatwork

@manatwork Untuk mengubah treeblok. Anda dapat mengubah ukurannya atau mengubah beberapa simbol sesuai keinginan Anda.
Wayne Cui

@WayneTsui ini tidak sesuai dengan persyaratan OP, "ukuran harus dipilih oleh beberapa metode input" dan "input yang lebih besar harus menghasilkan pohon yang lebih besar."
ulidtko

1
fungsi make-tree baru dari @kealist
Wayne Cui

4

Python

import sys
w = sys.stdout.write
def t(n,s):
    for i in range(n):
        for a in range(n-i):
            w(" ")
        w("[")
        for l in range(i<<1):
            if i==n-1:
                w("_")
            else:
                w("~")
        w("]")
        print("")
    for o in range(s):
        for i in range(n):
            w(" ")
        print("[]")

t(10, 2)

masukkan deskripsi gambar di sini


1

Ti-Basic 84

Meminta ukuran:

              :
            Input 
           S:Lbl 1
            S-1→S
              :
             "||
            "+""→
           Str1:" 
             "→Str2
         :Disp Str2+
        "   **":Disp 
       Str2+"  "+"*"+
      Str1+"*":Disp " 
     "+Str1+"*-"+"||-*
    ":Disp Str1+"*--||-
   -*":Disp "   *---||--
  -*":Disp "  *----||----
 *":Disp Str1+"   "+Str2+"
":If S>0:Goto 2:Goto 1:Lbl 
              2

Output (ukuran 1):

       **
      *||*
     *-||-*
    *--||--*
   *---||---*
  *----||----*
       ||

1
Di mana ukurannya bisa dipilih? Ini adalah pohon ukuran tetap
Justin

1
@ Quincunx Diperbaiki.
Timtech

4
-1; Anda tidak bisa hanya menyisipkan spasi putih sewenang-wenang ke dalam program TI-Basic.
lirtosiast
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.