pythonic生物人

Christmas tree in code~~

分享一些有意思的Christmas tree代码,包含Python、R、Java、shell等实现,小编最爱shell和R那个~~

Image

代码,

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;

/**
 * https://codegolf.stackexchange.com/questions/15860/make-a-scalable-christmas-tree
 * @author Quincunx
 */

publicclassChristmasTree{
publicstaticdouble scale = 1.2;

publicstaticvoidmain(String[] args){
        SwingUtilities.invokeLater(new Runnable() {
@Override
publicvoidrun(){
new ChristmasTree();
            }
        });
    }

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

        }
    }

classJImageextendsJPanelimplementsMouseListener{

        BufferedImage img;

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

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

publicvoidsetImage(BufferedImage image){
            img = image;
            repaint();
        }

@Override
publicvoidmouseClicked(MouseEvent me){
            System.exit(0);
        }

@Override
publicvoidmousePressed(MouseEvent me){

        }

@Override
publicvoidmouseReleased(MouseEvent me){

        }

@Override
publicvoidmouseEntered(MouseEvent me){

        }

@Override
publicvoidmouseExited(MouseEvent me){

        }
    }
}

ImageImage

代码,

# https://github.com/sergiolepore/ChristBASHTree
# tree-EN.sh

#!/bin/bash
trap "tput reset; tput cnorm; exit"2
clear
tput civis
lin=2
col=$(($(tput cols) / 2))
c=$((col-1))
est=$((c-2))
color=0
tput setaf 2; tput bold

# Tree
for ((i=1; i<20; i+=2))
{
    tput cup $lin $col
for ((j=1; j<=i; j++))
    {
        echo -n *
    }
    let lin++
    let col--
}

tput sgr0; tput setaf 3

# Trunk
for ((i=1; i<=2; i++))
{
    tput cup $((lin++)) $c
    echo 'mWm'
}
new_year=$(date +'%Y')
let new_year++
tput setaf 1; tput bold
tput cup $lin $((c - 6)); echo MERRY CHRISTMAS
tput cup $((lin + 1)) $((c - 10)); echo And in $new_year:
let c++
k=1

# Lights and decorations
while true; do
for ((i=1; i<=35; i++)) {
# Turn off the lights
        [ $k -gt 1 ] && {
            tput setaf 2; tput bold
            tput cup ${line[$[k-1]$i]} ${column[$[k-1]$i]}; echo \*
            unset line[$[k-1]$i]; unset column[$[k-1]$i]  # Array cleanup
        }

        li=$((RANDOM % 9 + 3))
        start=$((c-li+2))
        co=$((RANDOM % (li-2) * 2 + 1 + start))
        tput setaf $color; tput bold   # Switch colors
        tput cup $li $co
        echo o
        line[$k$i]=$li
        column[$k$i]=$co
        color=$(((color+1)%8))
# Flashing text
        sh=1
for l in 搞钱搞钱搞钱
        do
            tput cup $((lin+1)) $((c+sh))
            echo $l
            let sh++
            sleep 0.01
        done
    }
    k=$((k % 2 + 1))
done

bash tree-EN.sh

Image

动起来,

Image

代码,

# 加载R包
library(tidyverse)  # 数据处理和绘图
library(rlang)      # 元编程工具

# 导入主函数(假设grow_tree.R在工作目录的/R子目录中)
source('~/Desktop/grow_tree.R')  # https://github.com/R-CoderDotCom/christmas-tree/blob/main/christmas_tree.R 主函数:树形生长模拟函数

# 定义简单版本的角度、长度和存活率函数
angle_fun1  <- function(angle) angle + c(-0.1 * pi, 0.1 * pi) 
# 角度函数:子分支角度=父分支角度 ± 0.1π
length_fun1 <- function(length) 0.85 * length
# 长度函数:子分支长度=父分支长度的85%
surv_fun1   <- function() 0.9
# 存活概率函数:两个子分支都有90%存活率

# 设置随机种子保证结果可重复
set.seed(12345)

# 生成第一棵树(10次迭代)
tree1 <- grow_tree(n_iter     = 10, 
                   angle_fun  = angle_fun1(angle), 
                   length_fun = length_fun1(length), 
                   surv_fun   = surv_fun1(),
                   verbose    = FALSE)  # 不显示进度

# 绘图(only_living = TRUE只绘制存活的枝条)
# plot_tree(tree1, only_living = TRUE)  # 注释掉了,但功能是绘制枝干

# 定义复杂版本的角度函数
# 角度是代数和父角度的函数
# 对称分叉,树冠越高平均角度和角度变异越大
angle_fun2  <- function(angle, generation){
# 权重随代数增加而增大
  w  <- 1 - 1 / generation
# 从父分支角度获取绝对偏差
  a0 <- rnorm(1, 0.12 * w * pi, 0.05 * w * pi)
# 返回随机顺序的新角度
  angle + sample(c(-a0, a0))
}

# 复杂长度函数:作为父长度的函数,平均减少10%,有随机变异
length_fun2 <- function(length) rnorm(2, 0.9, 0.05) * length

# 复杂存活率函数:与代数和迭代次数相关
# 一个分支以95%的概率存活,另一个分支的存活率随树龄增加
# (看起来更真实,因为看起来像断枝)
surv_fun2   <- function(generation, n_iter) c(.75 - (n_iter - generation[1]) / (2 * n_iter), .95)

# 设置随机种子
set.seed(999)

# 生成第二棵树(25次迭代)
tree2 <- grow_tree(n_iter = 25, 
                   angle_fun2(angle, generation), 
                   length_fun2(length), 
                   surv_fun2(generation, 25),  # 注意:n_iter需要明确指定
                   verbose = FALSE)

# 绘制树
# plot_tree(tree2)  # 注释掉了,但功能是绘制树(包括叶子)

# 清理第二棵树(去除死枝等)
tree2_clean <- clean_tree(tree2)

# 设置随机种子
set.seed(13579)

# 从第25代终端分支的基部随机抽取30个点作为装饰球位置
baubles <- filter(tree2_clean, 
                  generation == 25,  # 选择第25代
                  pos == 0) %>%      # 选择分支起点
  sample_n(30)                      # 随机抽取30个

# 将装饰球添加到树上
# 手动创建清理后树的图形
p1 <- tree2_clean %>% 
    ggplot(aes(x = x,           # x坐标
               y = y,           # y坐标
               group = id,      # 分组(每个分支)
               size = 1 / generation,  # 线条粗细:代数越大线条越细
               color = generation)) +  # 颜色按代数渐变
    geom_line(lineend = "round") +     # 绘制圆头线条
    scale_color_tree() +               # 自定义颜色标度
    theme_void() +                     # 无坐标轴和背景
    theme(legend.position = "none") +  # 隐藏图例
    coord_equal()                      # 等比例坐标

# 添加装饰球
p1 +
# 红色装饰球带黑色轮廓
  geom_point(data = baubles, aes(x = x, y = y), 
             fill = "#AA1243", col = 1, pch = 21, size = 5) +
# 白色透明高光(小幅偏移避免在中心)
  geom_point(data = baubles, aes(x = x, y = y), 
             col = "white", alpha = 0.3, size = 1,
             position = position_nudge(x = -0.08, y = 0.08)
            )

# 注意:最后两行是装饰球,模拟圣诞树装饰
# 1. 红色球体带黑色边框
# 2. 白色小亮点模拟反光效果

Image

代码,

# Mathematica 
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]

Image

代码,

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

#define PI 3.14159265359

float sx, sy;

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

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

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

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

intribbon(){

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

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

Image

代码,

# https://github.com/R-CoderDotCom/christmas-tree
# 定义绘图函数,参数控制是否显示灯泡、雪花、星星和背景色
chtree <- function(bulbs = TRUE, snow = TRUE, star = TRUE, bg.col = 1){
  set.seed(1)  # 设置随机种子保证结果可重现

  p <- points  # 创建快捷别名
  r <- runif
  l <- 500
  s <- (l:1)/1000

# 设置图形参数:背景色、点符号、边距
  par(bg = bg.col, pch = 8, mar = rep(0, 4))
# 创建空白画布
  plot(0, xlim = c(-1.25, 1.25), axes = F, xlab = "", ylab = "", ylim = c(-100, 550))
  a <- 0

# 绘制树干
  rect(-0.1, -100, 0.1, 0, col = "brown", border = "brown")

# 绘制星星光晕(多层半透明圆点制造发光效果)
if(isTRUE(star)) {
for(i in11:1){
      points(0.005, 500.2, pch = 19, col = rgb(1, 1, 0, 0.05), cex = 5 + (0.65 * i))
    }
  }

# 绘制树冠主体(多层水平线模拟松针)
for(i in rep(exp(-(1:125)* 0.016), 4) * s + s){
    a <- a + 1
for(j in seq(-i, i, 0.02)){
      p(j, a, col = rgb(0, i*.7 + 0.2 * r(1, 0.6, 1) - 0.5 * j^2, 0))
    }
  }

# 绘制彩灯装饰
if(isTRUE(bulbs)) {
# 生成随机颜色
    cols <- sample(c(rgb(1, 0, 0, 0.1), rgb(0, 1, 0, 0.1), rgb(1, 1, 0, 0.1), rgb(0, 0.2, 1, 0.1)))
    cols2 <- sample(c(rgb(1, 0, 0, 0.1), rgb(0, 1, 0, 0.1), rgb(1, 1, 0, 0.1), rgb(0, 0.2, 1, 0.1)))
    cols3 <- sample(c(rgb(1, 0, 0, 0.1), rgb(0, 1, 0, 0.1), rgb(1, 1, 0, 0.1), rgb(0, 0.2, 1, 0.1)))
    cols4 <- sample(c(rgb(1, 0, 0, 0.1), rgb(0, 1, 0, 0.1), rgb(1, 1, 0, 0.1), rgb(0, 0.2, 1, 0.1)))

# 绘制多层灯泡(逐层缩小半径)
for(i in11:1){
      points(seq(-1, 1, 0.1), rep(0, 21), pch = 19, col = cols, cex = 0.15 + (0.12 * i))
      points(seq(-0.75, 0.75, 0.1), rep(125, 16), pch = 19, cex = 0.15 + (0.12 * i), col = cols2)
      points(seq(-0.5, 0.5, 0.1), rep(250, 11), pch = 19, cex = 0.15 + (0.12 * i), col = cols3)
      points(seq(-0.25, 0.25, 0.1), rep(375, 6), pch = 19, cex = 0.15 + (0.12 * i), col = cols4)
    }

# 添加随机分布的大装饰球
    set.seed(60)
    points(runif(6, -0.77, 0.77), runif(6, 0, 100), pch = 21, cex = 3, bg = sample(c("gold", "red")))
    set.seed(2)
    points(runif(7, -0.5, 0.5), runif(7, 125, 300), pch = 21, cex = 3, bg = sample(c("gold", "red")))
    set.seed(5)
    points(runif(4, -0.2, 0.2), runif(4, 300, 370), pch = 21, cex = 3, bg = sample(c("gold", "red")))
    points(0, 140, pch = 21, cex = 3, bg = sample(c("gold", "red")))
    points(-0.15, 180, pch = 21, cex = 3, bg = sample(c("gold", "red")))
  }

# 绘制星星
if(isTRUE(star)) {
    points(0.006, 508, pch = 19, col = 7, cex = 5.6)  # 底座
    p(0, 520, pch = "⭐", cex = 13, col = 7)           # 星星符号
  }

# 绘制雪花
if(isTRUE(snow)) {
    p(r(75, -1.25, 1.25), r(75, -100, l+50), col = "white", cex = sample(seq(0.5, 1.2, length.out = 75)), pch = "❄️")
    p(r(100, -1.25, 1.25), r(100, -100, -95), col = "white", cex = sample(seq(0.5, 1.2, length.out = 75)), pch = "❄️")
  }
}

# 调用函数绘制默认圣诞树
chtree()

👉Python matplotlib可视化教程

图片

👉Python seaborn可视化教程

图片
👉R可视化教程
图片
图片

加入学习👇

图片