Crea un albero di Natale scalabile [chiuso]


95

La tua sfida: crea un albero di Natale. La dimensione deve essere selezionabile con un metodo di input, ma non deve essere direttamente correlata a nessuna parte dell'albero; tuttavia, input più grandi dovrebbero produrre un albero più grande.

Come puoi farcela? Puoi realizzare l'albero come preferisci, tranne stampando il carattere unicode per l'albero , come ad esempio un'immagine in rilievo, arte ascii, con altri aspetti, ecc. Qualunque cosa tu faccia, ricorda che questo è un , quindi essere creativo.

La risposta con il maggior numero di voti entro la fine di dicembre vince, ma ne accetterò un altro se aumenta


1
Bella domanda;)
Timtech,

1
Le decorazioni di peccato non erano obbligatorie!
o0 '.

@Lohoris Penso che sia positivo che non siano obbligatori. In questo modo, le persone possono fare ciò che vogliono e quei brillanti alberi frattali sono risposte legittime.
Giustino,

@Quincunx potresti aggiungere decorazioni anche agli alberi frattali ...
o0 '.

@Lohoris sì, ma sono tanti com'è. L'autore di quegli alberi potrebbe aggiungere decorazioni se lo desiderano, ma preferirei non richiederlo.
Giustino,

Risposte:


92

Pitone

Un albero di Natale frattale con il pacchetto tartaruga:

inserisci qui la descrizione dell'immagine

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 è il parametro size, l'albero mostrato è per n = 50. Richiede un minuto o due per disegnare.


2
Sembra adorabile:)
Soner Gönül

80

JavaScript

enter image description here

Mostra l'albero animato 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);

Mi piace, ma dovresti aggiungere un bagagliaio.
Fels il

1
@Fels ha aggiunto trunk
Howard il

2
È davvero impressionante, ma che succede con quei pixel verdi che circondano l'albero? Non mi rendevo conto che Babbo Natale aveva piccoli elfi verdi che potevano volare. (non toglie nulla alla bellezza della tua risposta, ma mi chiedo da dove vengano)
Giustino il

@Quincunx: sembrano essere punti campione iniziali prima della convergenza dell'iterazione. Saltare i primi 100 punti si libera di loro.
Ilmari Karonen,

2
Davvero bello, ma non sembra proprio un albero di Natale. Sembra più un bastone con alcune foglie di felce attaccate ad esso. Inoltre, potresti far scorrere lentamente la vista lungo l'asse y, quindi il 3D-ness è più evidente?
The Guy with The Hat,

76

Ancora un altro albero delle lingue Mathematica / Wolfram basato sulla risposta di 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]

Christmas tree


7
Questo è il migliore!!
Murta,

63

Javascript

Output of given code sample

Questo è il mio primo codice golf!

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

Entra in 295 personaggi.

Le dimensioni e la decorazione dell'albero sono impostate dalle variabili a, b, c:

  • a imposta la quantità di righe nell'albero
  • b imposta la quantità di file tra le diminuzioni in larghezza (impostare in basso per un albero magro, in alto per un albero grasso). Deve essere maggiore o uguale a 3.
  • c imposta la quantità di palline (imposta zero per nessuna, 1 per solo palline, numeri più alti per un posizionamento meno denso di palline)

Sembra migliore quando a è un multiplo di b, come nell'esempio.

Incolla nella console per creare un albero. Sembra migliore da molto lontano!


1
ridotto a 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
Stai davvero giocando a golf in una gara di popolarità? Wow, avrei scritto un bel codice leggibile (più facile da inserire). +1
Giustino,

7
ungh. Stai usando doc.write? Nessun +1 da parte mia.
John Dvorak,

2
@JanDvorak, Perché no? Pensavo che questo fosse golf .....
Pacerier

62

C ++

Facciamolo nello spirito di IOCCC e abbiamo anche il codice a forma di albero! : 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;;;}}

Accetta un numero intero come input e restituisce un albero di Natale con tanti "livelli di stack". Ad esempio, un input di

5

Ritorna:

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

esempio di output?
John Dvorak,

32
Il codice sembra più un albero di Natale che l'output ...
Denys Séguret,

2
@dystroy per la cronaca, le istruzioni non dicono che è l'output che deve contenere l'albero.
Pierre Arlaud,

4
@ArlaudPierre: Ma la dimensione deve essere regolabile, il che è impossibile solo con il codice sorgente. Ho potuto fare un programma che genera il codice del programma nella forma di un albero di Natale che emette un vero e proprio albero di Natale, ma immagino che sarebbe terribilmente difficile, senza ricorrere a solo l'inserimento di un punto e virgola randagi ovunque.
Joe Z.

1
Se metti a *nella parte superiore dell'albero (codice sorgente), avrai il mio +1.
Fabricio,

61

Javascript

Generatore di alberi di abete procedurale completamente 3D quasirealistico.

Dotato di: ampia configurazione con ancora più opzioni di configurazione presenti nel codice; un tronco a zig-zag; rami ramificati; animazione di crescita; rotazione di un albero completamente cresciuto.

Non caratterizzato da: jQuery, Underscore.js o qualsiasi altra libreria; dipendenza hardware: è richiesto solo il supporto canvas; codice disordinato (almeno questa era l'intenzione)

Pagina live: http://fiddle.jshell.net/honnza/NMva7/show/

Modifica pagina: http://jsfiddle.net/honnza/NMva7/

immagine dello schermo:

abete

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
Lo so perché questa risposta ha un solo commento: perché lascia le persone senza parole.
Caridorc,

49

bash

Uscita campione:

Albero di Natale ASCII

La dimensione dell'albero (ovvero il numero di righe) viene passata sulla riga di comando ed è limitata a valori di 5 o più. L'immagine sopra è stata prodotta dal comando ./xmastree.sh 12. Ecco il codice sorgente:

#!/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 " "

È molto carino.
Pandubear il

42

Disclaimer: si basa sul mio albero di Natale LaTeX, pubblicato per la prima volta qui: https://tex.stackexchange.com/a/87921/8463

Il codice seguente genererà un albero di chrismtas, con decorazioni casuali. Puoi cambiare sia la dimensione dell'albero, sia il seme casuale per generare un albero diverso.

Per cambiare il seme modifica il valore interno \pgfmathsetseed{\year * 6}in qualsiasi altro valore numerico (quello predefinito genererà un nuovo albero ogni anno)

Per modificare la dimensione dell'albero, modifica l'opzione order=10per renderla più grande o più piccola a seconda della dimensione dell'albero che desideri.

Esempi. order=11:

inserisci qui la descrizione dell'immagine

order=8

inserisci qui la descrizione dell'immagine

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

Direi che questo è basato sull'albero di Stefan Kottwitz, pubblicato per la prima volta qui . Dire che si basa sul tuo albero sembra che tu abbia scritto tutto il codice per questo, il che non è vero. Qualcun altro ha scritto la maggior parte del codice per l'albero reale.
The Guy with The Hat

@RyanCarlson l'idea di utilizzare il sistema LindenMayer come base per applicare decorazioni è stata la mia idea, e se controlli attentamente entrambi i codici che puoi vedere, che la parte Lindenmayer del codice è stata riprogettata per avere anche parti aggiuntive (come un radice per l'albero, che manca all'originale). Oltre a ciò non ho dimenticato di fare riferimento all'originale, in cui chiunque può verificare i riferimenti (incluso quello a Peitgen e Saupe, che potrebbero essere stati i primi a redigere l'equazione dell'albero)
SztupY,

34

Befunge 93

Questo è un albero non decorato:

&::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-
"||"$ <@,,

Uscita di esempio, l'ingresso è 10:

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

Aggiungiamo alcune decorazioni:

&::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-
"||"$ <@,,

Uscita campione:

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

32

HTML e 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>

Sono supportate dimensioni tra 1 e 25: basta aggiungere la dimensione all'URL come identificatore di frammento.

Funziona in Chrome, Explorer e Firefox. In Opera è brutto, ma la parte in scala funziona.

Esempio di accesso:

http://localhost/xmas.html#5

albero di natale di dimensioni 5

Esempio di accesso:

http://localhost/xmas.html#15

albero di natale di dimensioni 15

Dal vivo:

http://dabblet.com/gist/8026898

(La visualizzazione live non contiene CSS con prefisso fornitore e include collegamenti per modificare le dimensioni.)


1
+1 Mi piace l'idea di utilizzare :targetper ridimensionare l'output :-)
ossifrage schizzinoso

32

Giava

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

        }
    }
}

Per modificare le dimensioni, cambia scale passa a qualche altro doppio valore (tienilo attorno a 1 se vuoi vedere qualcosa).

Esempio di output (per 1,0 come scala, troppo pigro per fare uno screenshot, quindi ho appena pubblicato quello che fa):

inserisci qui la descrizione dell'immagine

Il programma prende questa immagine da Internet, la ridimensiona in base a scale, quindi la mette in una finestra non decorata dove viene visualizzata. Cliccando sulla finestra si chiude il programma. Inoltre, il testo del suggerimento è presente, ma il collegamento no.


3
Questo non è "disegnare" nulla.
Mrchief,

@Mrchief La sfida non è disegnare qualcosa; è fare un albero. Questo sta facendo un albero, prendendo l'immagine
Giustino il

2
Hai generato tu stesso l'immagine? No. Lo stai scaricando da qualche parte. La domanda non è scaricare un'immagine e ridimensionarla. Controlla le altre risposte e capirai cosa ha effettivamente richiesto l'OP.
Mrchief,

10
@Mrchief Hai notato chi ha scritto il PO? Questa è una delle molte possibili soluzioni che stavo cercando quando ho posto questa domanda.
Justin il

3
Ha! Smack sulla testa! Dal momento che è il tuo post, non vedo molte ragioni per discutere, oltre a esprimere la mia opinione che questo non è lo stesso del tuo codice "fare" qualcosa (come fanno le altre risposte). Proprio come scaricare un film non è lo stesso di fare un film.
Mrchief,

28

TI-89 Basic

Solo perché volevo vedere un albero di Natale sulla mia calcolatrice. Lo scriverò qui come appare sulla mia calcolatrice.

: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

Funziona allo stesso modo della mia risposta Befunge, ma io uso ornamenti diversi. Sì, gli elementAtusi ripetuti della mia funzione rallentano il programma a causa di molte conversioni tra liste e matrici, ma come ho scritto prima, ho deciso di non modificarlo. Inoltre, ho imparato durante la digitazione di questa risposta che ©fa un commento (ho pensato che sembrava @, ma che è un altro personaggio). Non ho mai saputo cosa fosse prima d'ora.

Uscita campione:

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

Adoro quelli ; sembrano bastoncini di zucchero.


Che versione è questa?
SuperJedi224,

@ SuperJedi224 L'ho aggiunto alla risposta
Giustino il

27

Wolfram Language ( Mathematica )

Come discusso nel famoso thread di Reddit: t * sin (t) ≈ Albero di Natale

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]

inserisci qui la descrizione dell'immagine


Dove si imposta la dimensione e come influenza l'albero generato?
arte

2
@manatwork questo è fondamentalmente grafico t*sin(t)come ho detto nel post. Quindi complottare per t più grandi farà solo un albero più grande:Table[..., {t, 0, 200, PD}]
Vitaliy Kaurov,

24

Bash con Bc e 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:

Esecuzione di esempio:

bash-4.1$ ./xmas.sh 5

Uscita campione:

albero di natale di dimensioni 5

Esecuzione di esempio:

bash-4.1$ ./xmas.sh 15

Uscita campione:

albero di natale di dimensioni 15


23

C

Uscita campione per profondità = 4, zoom = 2.0

Albero

Questa risposta utilizza un approccio abbastanza diverso dalle altre risposte. Genera una struttura ad albero ramificandosi ricorsivamente. Ogni ramo è rappresentato da una serie di cerchi. E infine la funzione principale campiona i cerchi e si riempie di caratteri quando si incontrano i cerchi. Poiché viene eseguito campionando una scena (come il ray-tracing), è intrinsecamente scalabile. Il rovescio della medaglia è la velocità, poiché attraversa l'intera struttura ad albero per ogni "pixel"!

Il primo argomento della riga di comando controlla la profondità della ramificazione. E la seconda scala dei controlli (2 significa 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
Penso che sia sicuro affermare che questa sia la risposta tecnicamente più impressionante a questa domanda finora.
Stuntddude

20

Mathematica ASCII

Mi piace molto l'arte ASCII, quindi aggiungo un'altra risposta molto diversa - soprattutto quindi è così breve in Mathematica:

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

inserisci qui la descrizione dell'immagine

E ora con un po 'più di raffinatezza un albero ASCII dinamico scalabile. Guarda da vicino - anche l'albero sta cambiando - la neve si attacca ai rami e poi cade ;-)

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 -> {}]
  ]
 ]

inserisci qui la descrizione dell'immagine


Ben fatto. Dove si regola la dimensione? Sono 35 nei Tableparametri di?
arte

@manatwork sì, il 35 in tabella. Grazie;)
Vitaliy Kaurov

19

Ho fatto questo per una sfida su / r / dailyprogrammer , (non sono sicuro che il riutilizzo del codice sia contrario allo spirito / alle regole di questo) ma:

Brainfuck. Accetta come input un numero (lunghezza della riga inferiore delle foglie) e due caratteri. Uno spazio tra ciascuno.

Esempio di input: 13 = +

Esempio di output:

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

Codice:

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

1
Finalmente una risposta geniale!
Pharap,

16

in lavorazione

L'albero di Natale originale frattale. La posizione Y del mouse determina le dimensioni, utilizzare i tasti freccia su e giù per modificare il numero di generazioni.

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

Che bel albero di Natale, non credi, mamma?

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

Sono super deluso dal fatto che qualcuno mi abbia battuto nel pubblicare un albero frattale anche se ero davanti a loro nell'idea e in realtà ho iniziato a lavorare su di esso: /


14

Rubino

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

Felice anno nuovo

È possibile personalizzare l'output cambiando *.
Per un albero verde:((1..20).to_a+[6]*4).map{|i|puts "\e[32m"+('*'*i*2).center(80)}

Approccio 2 (albero di Natale che non sembra una freccia)

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

Felice anno nuovo

Approccio 3

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

2
Questa è più una freccia, quindi un albero di Natale!
klingt.net,

4
@ klingt.net * di.
NARKOZ,

È ora di illuminare l'albero di Natale.
NARKOZ,

E dove si specifica la dimensione?
arte

@manatwork in intervalli. 1..20, 1..6ecc.
NARKOZ,

14

Grafica di tartaruga

inserisci qui la descrizione dell'immagine

Basato sulle proprietà della spirale di Eulero .

Codice:

inserisci qui la descrizione dell'immagine

La scala è determinata dalla dimensione del gradino ( move forward by: 6). Una versione interattiva è disponibile qui .

PS Ispirato da questa domanda.


Dov'è questo "scalabile"? A parte questo, è fantastico!
Justin l'

@Quincunx Puoi cambiare scala cambiando move forward by 6. Ad esempio, 10produrrà un albero più grande. In realtà non c'è input in questo "linguaggio" (o l'intero codice può essere trattato come input;)).
Ybeltukov,

14

in lavorazione

Ho creato questo generatore di alberi usando un sistema L e una tartaruga.

Un albero

codice:

//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
Sì! Un sistema L!
Luser droog,

1
Concordo sul fatto che sia il più realistico :)
Timtech,

@Timtech Non sono d'accordo. Penso che questa sia la seconda più realistica, dopo la risposta Javascript di Jan Dvorak . Voglio dire, guarda quegli aghi (su questo)! Sono tutti raggruppati in schemi che non ho visto su un albero sempreverde. Tuttavia, l'albero di Jan mi assomiglia molto ad un abete.
Justin il

1
@Quincunx Devo aver perso quello. Comunque, questo sembra piuttosto buono.
Timtech,

L'albero di @Quincunx Jan - e anche quello di Howard - è davvero bello, ma non necessariamente del tutto realistico . Jan ammette persino che l'albero è solo "quasirealistico". - RyanCarlson 10 secondi fa
The Guy with The Hat

12

JavaScript (eseguito su qualsiasi pagina della console)

Stavo giocando a golf, ma poi ho deciso di non farlo, quindi come puoi vedere ci sono tonnellate di numeri magici: 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)

Risultato per s = 300:

immagine dello schermo

s = 600:

immagine dello schermo


2
Decorerai l'albero? :-)
Justin

1
@Quincunx Forse, potrei lavorarci più avanti :)
Maniglia della porta

2
GAH! Dove sono i punti e virgola ?!
Andrew Larsson,


10

Lingua di Game Maker

spr_tree

spr_tree

L'albero crea un evento

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

Room, 402 by 599

L'albero è posto a (0,0)

Bonus! È possibile ridimensionare l'albero di Natale dopo l'input iniziale con i tasti 0-9.


8

Risposta AppleScript + SE

In realtà, l'ho scoperto per caso durante la modifica di una risposta a questa domanda. Vai a capire.

Usalo eseguendo il codice, digitando il numero che desideri, scorrendo sul post SE e facendo clic nel campo di testo. Questo sfrutta il fatto che lo stack di virgolette.

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

Uscita (input 50):

>


6

Albero FORTRAN decorato

    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

L'albero ha una gamma limitata di dimensioni, ma ritiene che rifletta accuratamente la vita della maggior parte degli alberi di Natale.

Dall'albero infantile:

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

All'albero dell'adolescente:

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

Per adulti:

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

5

Giava

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

Risultati del campione:

Size = 3:

inserisci qui la descrizione dell'immagine

Size = 4:

inserisci qui la descrizione dell'immagine

Size = 5:

inserisci qui la descrizione dell'immagine

Size = 12:

inserisci qui la descrizione dell'immagine

Size = 20:

inserisci qui la descrizione dell'immagine


1
Non l'ho notato prima. Super cool +1
uno spaghetto il

4

Rebol

Con un dialetto per visualizzare i simboli. Per modificare la dimensione dell'albero, basta cambiare il parametro di 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

un albero con 3 strati un albero con 5 strati


3
Dove si imposta la dimensione e come influenza l'albero generato?
arte

@manatwork Per modificare il treeblocco. Puoi ridimensionarlo o modificare alcuni dei simboli a tuo piacimento.
Wayne Cui,

@WayneTsui questo non è conforme ai requisiti del PO, "la dimensione deve essere selezionabile con un metodo di input" e "input più grandi dovrebbero produrre un albero più grande".
Ulidtko,

1
una nuova funzione make-tree di @kealist
Wayne Cui il

4

Pitone

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)

inserisci qui la descrizione dell'immagine


1

Ti-Basic 84

Chiede una taglia:

              :
            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

Uscita (dimensione 1):

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

1
Dove è la dimensione selezionabile? Questo è un albero di dimensioni fisse
Justin il

1
@Quincunx Risolto.
Timtech,

4
-1; non puoi semplicemente inserire spazi bianchi arbitrari in un programma TI-Basic.
lirtosiast
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.