Зробіть масштабовану ялинку [закрито]


95

Ваше завдання: Зробіть ялинку. Розмір повинен бути обраний деяким методом введення, але він не повинен бути безпосередньо пов'язаний з будь-якою частиною дерева; однак, більші вхідні матеріали повинні створювати більше дерево.

Як можна це зробити? Ви можете зробити дерево будь-яким способом, який вам подобається, за винятком друку символу unicode для дерева , наприклад, витіснення зображення, мистецтва ascii з іншими аспектами і т. Д. Що б ви не робили, пам’ятайте, що це , так будь креативним.

Відповідь з найбільшою кількістю результатів до кінця грудня виграє, але я прийму іншу, якщо вона стане вищою


1
Приємне запитання;)
Timtech

1
Шкода прикраси не були обов'язковими!
o0 '.

@Lohoris Я думаю, що добре, що вони не є обов'язковими. Таким чином, люди можуть робити те, що хочуть, і ті блискучі фрактальні дерева є законними відповідями.
Джастін

@Quincunx ви можете додати прикраси навіть до фрактальних дерев ...
o0 '.

@Lohoris так, але їх багато, як є. Автор цих дерев міг би додати прикраси за бажанням, але я краще цього не вимагатиму.
Джастін

Відповіді:


92

Пітон

Фрактальна ялинка за допомогою пакета черепах:

введіть тут опис зображення

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 - параметр розміру, показане дерево для n = 50. На малювання потрібна хвилина-дві.


2
Це виглядає чудово:)
Soner Gönül

80

JavaScript

введіть тут опис зображення

Покажіть анімаційне дерево в Інтернеті .

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

Мені це подобається, але слід додати тулуб.
Fels

1
@Fels додав багажник
Говард

2
Це дуже вражає, але що з тими зеленими пікселями, що кружляють по дереву? Я не усвідомлював, що у Санта є маленькі зелені ельфи, які вміють літати. (вони не заважають красі вашої відповіді, але мені цікаво, звідки вони взялися)
Джастін

@Quincunx: Вони, здається, є початковими точками вибірки раніше, ніж ітерація сходиться. Пропуск перших 100 балів позбавляється від них.
Ільмарі Каронен

2
Дійсно класно, але це не зовсім схоже на ялинку. Він більше схожий на паличку з кількома прикріпленими до неї листям папороті. Крім того, чи можете ви змусити подання повільно прокручуватись по осі y, щоб 3D-гнізда була більш очевидною?
Хлопець з капелюхом

76

Ще одне дерево мови Mathematica / Wolfram на основі відповіді Віталія :

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]

Різдвяна ялинка


7
Це найкращий !!
Мурта

63

Javascript

Виведення даного зразка коду

Це мій перший гольф з кодом!

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

Він надходить у 295 персонажів.

Розмір і прикраса дерева встановлюються змінними a, b, c:

  • набір кількості рядків у дереві
  • b встановлює кількість рядків між зменшенням ширини (встановлюється низьким для худого дерева, високим для жирного дерева). Повинен бути більшим або рівним 3.
  • c встановлює кількість дрібниць (встановити нуль для жодних, 1 лише для дрібниць, більш високі числа для менш щільного розміщення дрібниць)

Найкраще це виглядає, коли а є кратним b, як у прикладі.

Вставте в консоль, щоб створити дерево. Виглядає краще здалеку!


1
зменшено до 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>");
користувач1886419

4
Ви справді займаєтесь гольфом на конкурсі популярності? Нічого собі, я б написав хороший читабельний код (простіше в коді). +1
Джастін

7
невірно. Ви використовуєте doc.write? Ні +1 від мене.
Джон Дворак

2
@JanDvorak, чому б і ні? Я б подумав, що це гольф .....
Pacerier

62

C ++

Давайте зробимо це в дусі IOCCC і матимемо також код у формі дерева! : 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;;;}}

Бере ціле число в якості введення і повертає ялинку з такою кількістю "стеків рівнів". Наприклад, введення

5

Повернення:

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

приклад виводу?
Джон Дворак

32
Код більше схожий на ялинку, ніж вихід ...
Denys Séguret

2
@dystroy для запису, інструкція не говорить про те, що результат повинен містити дерево.
П'єр Арло

4
@ArlaudPierre: Але розмір повинен бути регульованим, що неможливо лише з вихідним кодом. Я міг би зробити програму, яка виводить програмний код у формі ялинки, яка видає фактичну ялинку, але я думаю, що це було б дуже важко, не вдаючись просто вставляти скрізь збиті крапки з комою.
Джо Z.

1
Якщо ви покладете *на верхівку дерева (вихідний код), у вас буде мій +1.
Fabricio

61

Javascript

Квазіреалістичний повністю 3D-процедурний генератор ялинок.

Завдяки: розширена конфігурація з ще більшою кількістю параметрів конфігурації, наявних у коді; стовбур зигзаги; розгалуження гілок; анімація росту; обертання повністю вирощеного дерева.

Не містить: jQuery, Underscore.js або будь-яку іншу бібліотеку; апаратна залежність - потрібна лише підтримка полотна; безладний код (принаймні, таким був намір)

Жива сторінка: http://fiddle.jshell.net/honnza/NMva7/show/

Редагувати сторінку: http://jsfiddle.net/honnza/NMva7/

скріншот:

ялина

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
Я знаю, бо ця відповідь має лише один коментар: адже вона залишає людей безмовними.
Caridorc

49

Баш

Вибірка зразка:

ASCII Xmas дерево

Розмір дерева (тобто кількість рядків) передається в командному рядку і обмежується значеннями 5 або більше. Зображення вище було створено з команди ./xmastree.sh 12. Ось вихідний код:

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

Це дуже красиво.
pandubear

42

Відмова від відповідальності: це засновано на моїй ялинці LaTeX, вперше розміщеній тут: https://tex.stackexchange.com/a/87921/8463

Наступний код породжує дерево chriztas із випадковими прикрасами. Ви можете змінити як розмір дерева, так і випадкове насіння, щоб генерувати інше дерево.

Щоб змінити насіння, змініть значення всередині \pgfmathsetseed{\year * 6}на будь-яке інше числове значення (за замовчуванням кожен рік буде генерувати нове дерево)

Щоб змінити розмір дерева, змініть, order=10щоб він був або більшим, або меншим, залежно від розміру дерева, який ви хочете.

Приклади. order=11:

введіть тут опис зображення

order=8

введіть тут опис зображення

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

Я б сказав, що це засновано на дереві Стефана Котвіца, вперше розміщеному тут . Якщо сказати, що воно засноване на вашому дереві, це здається, що ви написали весь код для нього, що не відповідає дійсності. Хтось ще написав більшість коду для фактичного дерева.
Хлопець із Шапкою

@RyanCarlson ідея використовувати систему lindenmayer як основу для надягання прикрас була моєю ідеєю, і якщо уважно перевірити обидва коди, ви можете побачити, що частина коду lindenmayer була перероблена, щоб вона також мала додаткові частини (наприклад, корінь для дерева, якого не вистачає оригіналу). Крім того, я не забув посилатись на оригінал, де кожен може перевірити посилання (у тому числі на Пітгена та Сапе, які, можливо, першими склали рівняння дерева)
SztupY

34

Befunge 93

Це необроблене дерево:

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

Вибірка вибірки, вхід 10:

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

Додамо кілька прикрас:

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

Вибірка зразка:

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

32

HTML та 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>

Підтримуються розміри від 1 до 25 - просто додайте розмір до URL як ідентифікатор фрагмента.

Працює в Chrome, Explorer та Firefox. В Opera це некрасиво, але масштабування працює.

Приклад доступу:

http://localhost/xmas.html#5

ялинка розміром 5

Приклад доступу:

http://localhost/xmas.html#15

ялинка розміром 15

Живий перегляд:

http://dabblet.com/gist/8026898

(Живий вигляд не містить префіксованого CSS постачальника і включає посилання для зміни розміру.)


1
+1 Мені подобається ідея використання :targetдля масштабування результатів :-)
химерний ossifrage

32

Java

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

        }
    }
}

Щоб змінити розмір, перейдіть scaleдо іншого подвійного значення (утримуйте його близько 1, якщо хочете щось побачити).

Вибірка зразка (для 1,0 як масштаб, занадто ледачий, щоб зробити знімок екрана, тому щойно розмістив, що це робить):

введіть тут опис зображення

Програма знімає це зображення з Інтернету, змінює його розмір відповідно до цього scale, а потім розміщує його у незадекорованому вікні, де воно відображається. Клацання на вікні закриває програму. Також текст підказки інструменту є, але посилання немає.


3
Це нічого не "малює".
Mrchief

@Mrchief Завдання полягає не в тому, щоб намалювати щось; це зробити дерево. Це робить дерево, зробивши зображення
Джастін

2
Ви створили зображення самі? Ні. Ви просто завантажуєте його звідкись. Питання не в тому, щоб завантажити зображення та змінити його розмір. Перевірте інші відповіді, і ви зрозумієте, що насправді вимагала ОП.
Mrchief

10
@Mrchief Ви помітили, хто написав ОП? Це одне з безлічі можливих рішень, які я шукав, коли задав це питання.
Джастін

3
Га! Присмак по голові! Починаючи з вашого власного допису, я не бачу причин для того, щоб сперечатися, окрім висловлення своєї думки, що це не те саме, що ваш код "робить" щось (як решта відповідей). Як і завантаження фільму, це не те саме, що зробити фільм.
Mrchief

28

TI-89 Basic

Просто тому, що я хотів побачити ялинку на своєму калькуляторі. Я впишу його тут, як це відображається на моєму калькуляторі.

: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

Це працює так само, як і моя відповідь Befunge, але я використовую різні прикраси. Так, elementAtповторне використання моєї функції уповільнює програму через багато перетворень між списками та матрицями, але, як я писав це раніше, я вирішив проти редагування. Також я дізнався під час введення цієї відповіді, яка ©робить коментар (я думав, що це виглядає так @, але це вже інший персонаж). Ніколи не знав, що це було раніше.

Вибірка зразка:

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

Я люблю таких ; вони схожі на цукеркові тростини.


Що це за версія?
SuperJedi224

@ SuperJedi224 Я додав це у відповідь
Джастін

27

Мова Вольфрама ( Mathematica )

Як обговорювалося у знаменитій Reddit нитці: t * sin (t) ≈ ялинка

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]

введіть тут опис зображення


Де ви встановлюєте розмір і як він впливає на генероване дерево?
манатура

2
@manatwork це в основному графік, t*sin(t)як я вже говорив у публікації. Тож змова на великі т просто створить більше дерево:Table[..., {t, 0, 200, PD}]
Віталій Кауров

24

Bash з Bc та 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:

Проба зразка:

bash-4.1$ ./xmas.sh 5

Вибірка зразка:

ялинка розміром 5

Проба зразка:

bash-4.1$ ./xmas.sh 15

Вибірка зразка:

ялинка розміром 15


23

С

Вибірка зразка для глибини = 4, масштабування = 2,0

Дерево

Ця відповідь використовує підхід, що відрізняється від інших відповідей. Він створює структуру дерева шляхом рекурсивного розгалуження. Кожна гілка представлена ​​набором кіл. І, нарешті, основна функція відбирає кола та заповнює символи, коли кола виконуються. Оскільки це робиться шляхом відбору зразків сцени (наприклад, відстеження променями), вона є суттєво масштабованою. Мінусом є швидкість, оскільки вона обходить всю структуру дерева на кожен "піксель"!

Перший аргумент командного рядка керує глибиною розгалуження. А друга шкала управління (2 означає 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
Я думаю, що можна впевнено сказати, що це найбільш технічно вражаюча відповідь на це запитання досі.
Stuntddude

20

Mathematica ASCII

Мені дуже подобається мистецтво ASCII, тому я додаю ще одну зовсім іншу відповідь - тим більше, що це так коротко в Mathematica:

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

введіть тут опис зображення

А тепер з трохи більше вишуканості масштабоване динамічне дерево ASCII. Уважно стежте - дерево теж змінюється - сніг прилипає до гілок, тоді падає ;-)

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

введіть тут опис зображення


Хороший. Де ви регулюєте розмір? Це 35-ти Tableпараметри?
манантська робота

@manatwork так 35 в табл. Дякую;)
Віталій Кауров

19

Я зробив це для виклику / r / dailyprogrammer (не впевнений, чи повторне використання коду суперечить духу / правилам цього), але:

Брейнфук. Вводить як введення число (довжина нижнього ряду листя) та два символи. Один простір між кожним.

Приклад введення: 13 = +

Приклад виводу:

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

Код:

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

1
Нарешті, нахабна відповідь!
Фарап

16

Обробка

Оригінальна фрактальна ялинка. Положення миші Y визначає розмір, використовуйте клавіші зі стрілками вгору та вниз, щоб змінити кількість поколінь.

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

Яка мила ялинка, ти не думаєш, мамо?

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

Мене супер зіткнуло з тим, що хтось побив мене, щоб розмістити фрактальне дерево, навіть якщо я випереджав їх в ідеї і фактично починав роботу над цим: /


14

Рубін

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

Щасливого Нового року

Ви можете налаштувати вихід, змінивши *.
Для зеленого дерева:((1..20).to_a+[6]*4).map{|i|puts "\e[32m"+('*'*i*2).center(80)}

Підхід 2 (дерево Xmas, яке не схоже на стрілку)

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

Щасливого Нового року

Підхід 3

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

2
Це більше стрілка, то ялинка!
klingt.net

4
@ klingt.net *, ніж.
НАРКОЗ

Час запалити ялинку.
НАРКОЗ

А де ви вказуєте розмір?
манатура

@manatwork у діапазонах. 1..20, 1..6тощо.
НАРКОЗ

14

Графіка черепах

введіть тут опис зображення

На основі властивостей спіралі Ейлера .

Код:

введіть тут опис зображення

Шкала визначається розміром кроку ( move forward by: 6). Інтерактивна версія доступна тут .

PS Натхненний цим питанням.


Де ця «масштабована»? Крім цього, це чудово!
Джастін

@Quincunx Ви можете змінити масштаб, змінивши move forward by 6. Наприклад, 10буде виробляти більше дерево. Насправді в цій "мові" немає вводу (або весь код можна розглядати як вхідний;)).
ybeltukov

14

Обробка

Я створив цей генератор дерев за допомогою L-системи та черепахи.

Дерево

код:

//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
Так! L-система!
luser droog

1
Я згоден, що це найбільш реально :)
Timtech

@Timtech Я не згоден. Я думаю, що це другий найреалістичніший варіант після відповіді Яна Дворака на Javascript . Я маю на увазі, подивіться на ці голки (на цій)! Всі вони зібрані разом у візерунках, яких я не бачив на вічнозеленому дереві. Однак янове дерево мені дуже схоже на саджанець ялини.
Джастін

1
@Quincunx Я, мабуть, пропустив це. Все-таки ця виглядає досить непогано.
Timtech

Дерево @Quincunx Яна - і Говарда теж - справді круто, але не обов'язково повністю реалістично . Ян навіть визнає, що дерево є лише «квазіреалістичним». - RyanCarlson 10 секунд тому
Хлопець із капелюхом

12

JavaScript (запустити на будь-якій сторінці в консолі)

Я займався гольфом, але потім вирішив не робити, так як ви бачите, є ТОНИ чарівних чисел: 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)

Результат для s = 300:

скріншот

s = 600:

скріншот


2
Ви збираєтесь прикрасити дерево? :-)
Джастін

1
@Quincunx Можливо, я можу працювати над цим пізніше :)
Doorknob

2
GAH! Де крапки з комою ?!
Ендрю Ларссон


10

Мова виробника ігор

spr_tree

spr_tree

Дерево Створити подію

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

Кімната, 402 на 599

Дерево розміщено на (0,0)

Бонус! Ви можете змінити розмір ялинки після початкового введення за допомогою клавіш 0-9.


8

Відповідь AppleScript + SE

Насправді підхопили це випадково під час редагування відповіді на це запитання. Піди розберися.

Використовуйте це, запустивши код, ввівши потрібний вам номер, перетягніть його до повідомлення та натисніть на текстове поле. Це використовує той факт, що котирування стека.

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

Вихід (вхід 50):

>


6

Прикрашене дерево FORTRAN

    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

Дерево має обмежений діапазон розмірів, але, на його думку, воно точно відображає життя більшості ялинок.

З дерева немовляти:

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

До підліткового дерева:

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

Для дорослих:

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

5

Java

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

Приклад результатів:

Розмір = 3:

введіть тут опис зображення

Розмір = 4:

введіть тут опис зображення

Розмір = 5:

введіть тут опис зображення

Розмір = 12:

введіть тут опис зображення

Розмір = 20:

введіть тут опис зображення


1
Я цього раніше не помічав. Супер класний +1
спагетто

4

Rebol

З діалектом для відображення символів. Щоб змінити розмір дерева, просто змініть параметр 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

дерево з 3 шарами дерево з 5 шарами


3
Де ви встановлюєте розмір і як він впливає на генероване дерево?
манатство

@manatwork Щоб змінити treeблок. Ви можете змінити розмір або змінити деякі символи за своїм бажанням.
Уейн Куй

@WayneTsui це не відповідає вимогам ОП, "розмір повинен бути обраний деяким методом введення", а "більший вхід повинен створювати більше дерево".
ulidtko

1
нова функція make-tree від @kealist
Wayne Cui

4

Пітон

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)

введіть тут опис зображення


1

Ti-Basic 84

Запитує розмір:

              :
            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

Вихід (розмір 1):

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

1
Де вибрати розмір? Це дерево фіксованого розміру
Джастін

1
@Quincunx Виправлено.
Timtech

4
-1; не можна просто вставити довільну пробіл у програму TI-Basic.
lirtosiast
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.