Nastasia Griffioen
Nastasia Griffioen

Reputation: 91

R: Christmas Tree

For an assignment, we need to draw a Christmas tree in R. I've searched the internet and found some helpful pieces of advice, but at the end of the day, I don't know how to proceed and hope someone can help me.

This is my code so far.

#ctree: prints a Christmas tree on screen with size N
ctree <- function(N){
for (i in 1:N){
    width = sample("*",i,replace=T)
    cat(width,sep="-","\n")
    }   
cat(width[1],"\n")
}

This leaves me with the middle and right side of my tree (with N=4), which is great, but not enough.

*-
*-*-
*-*-*-
*-*-*-*-
*

I planned on reversing what I had (basically right-aligning the product of the function) to create the left side, subsequently delete the rightmost column of the left side and glue it together with the right side of the tree, creating a Christmas tree.

I really hope that someone can help me achieve this! Looking forward to your advice.

Thanks in advance.

Upvotes: 5

Views: 2900

Answers (3)

vonjd
vonjd

Reputation: 4380

Here is a more succinct version:

ctree <- function(N=10){
  for (i in 1:N) cat(rep("",N-i+1),rep("*",i),"\n")
  cat(rep("",N),"*\n")
}

ctree()

Upvotes: 3

lawyeR
lawyeR

Reputation: 7664

This code came from someone else. I wish I could credit them but I have lost the source. The tree it produces is beautiful, and perhaps you could modify it for your purposes.

part <- list(x0=0,y0=0,x1=0,y1=1,
             branch1=NULL,branch2=NULL,extend=NULL,
             lwd=1,depth=0,col='springgreen')

par(mfrow=c(1,1),mar=c(5, 4, 4, 2) + 0.1)
segplot <- function(tree) {
  if (is.null(tree)) return()
  segments(tree$x0,tree$y0,tree$x1,tree$y1,
           col=tree$col,
           lwd=tree$lwd)
  segplot(tree$branch1)
  segplot(tree$branch2)
  segplot(tree$extend)
}
#segplot(part)

grow <- function(tree) {
  if (is.null(tree) ) return(NULL)

  tree$lwd=tree$lwd*1.2
  if (tree$lwd>2.5) tree$col <- 'brown'
  if (is.null(tree$extend)) {
    tree$extend <- list(
      x0=tree$x1,
      y0=tree$y1,
      x1=rnorm(1,1,.03)*(2*tree$x1-tree$x0),
      y1=(rnorm(1,.98,.02)+.02*(tree$x1==tree$x0))*(2*tree$y1-tree$y0),
      branch1=NULL,
      branch2=NULL,
      extend=NULL,
      lwd=1,
      depth=tree$depth,
      col=tree$col
    )
    length=sqrt((tree$x1-tree$x0)^2 + (tree$y1-tree$y0)^2)
    angle <- asin((tree$x1-tree$x0)/length)
    branch <- list(
      x0=(tree$x1+tree$x0)/2,
      y0=(tree$y1+tree$y0)/2,
      branch1=NULL,
      branch2=NULL,
      extend=NULL,
      lwd=1,
      depth=tree$depth,
      col=tree$col
    )
    shift <- rnorm(2,.5,.1)
    branch$x0 <- shift[1]*tree$x1+(1-shift[1])*tree$x0
    branch$y0 <- shift[1]*tree$y1+(1-shift[1])*tree$y0
    length=length*rnorm(1,.5,.05)
    co <- runif(1,.35,.45)
    branch$x1 <- branch$x0+sin(angle+co)*length

    branch$y1 <- branch$y0+cos(angle+co)*length
    tree$branch1 <- branch
    branch$x0 <- shift[2]*tree$x1+(1-shift[2])*tree$x0
    branch$y0 <- shift[2]*tree$y1+(1-shift[2])*tree$y0
    co <- runif(1,.35,.45)
    branch$x1 <- branch$x0+sin(angle-co)*length
    branch$y1 <- branch$y0+cos(angle-co)*length
    tree$branch2 <- branch    
  } else {
    tree$branch1 <- grow(tree$branch1)
    tree$branch2 <- grow(tree$branch2)
    tree$extend <- grow(tree$extend)
  }
  tree$depth <- tree$depth+1
  if (tree$depth>2)  tree$col <- 'green'
  if (tree$depth>4)  tree$col <- 'darkgreen'
  if (tree$depth>6)  tree$col <- 'brown'

  tree
}
tree <- part
for (i in 1:9) tree <- grow(tree) 
par(mar=c(0,0,0,0))
plot(x=c(-3,3),y=c(0,9),type='n',axes=FALSE,xlab='',ylab='')
segplot(tree)

Upvotes: 1

Nastasia Griffioen
Nastasia Griffioen

Reputation: 91

For anyone interested: this is what I ended up doing in R to create a Christmas tree.

#ctree: prints a Christmas tree on screen with amount of branch levels N
ctree <- function(N){
filler = "*"
blank = ""

for (i in 1:N){
    row = c(sample(blank,N-i,replace=T),sample(filler,i,replace=T),sample(blank,N-i,replace=T))
    cat(row,"\n")
    }   
cat(c(sample(blank,(N-1),replace=T),sample(filler,1,replace=T),sample(blank,(N-1),replace=T)),"\n")
} #ctree

This being the result! My own happy little (or big, whatever floats your boat) tree.

enter image description here

Upvotes: 4

Related Questions