Advertisement
beason4251

Jaywalking Simulation

Nov 22nd, 2013
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 5.05 KB | None | 0 0
  1. library(caTools)         # external package providing write.gif() function
  2.  
  3. # sets up color palette funciton
  4. jet.colors <- colorRampPalette(c("#000000", "#00FF00", "#AAAA00",
  5.                                  "#FF0000", "#FFFFFF"))
  6. height <- 400 # height of gif in pixels
  7. width <- 200  # width of gif in pixels
  8. steps <- 1000 # number of times steps
  9.  
  10. accel <- -2 # acceleration; negative is up
  11. fric <- 0.5 # friction; resistance to movement
  12.  
  13. # initializes position array
  14. # columns are y, x, -vy, -vx, state
  15. # x is measured in pixels from the left
  16. # y is measured in pixels from the top
  17. # state is whether a person is jaywalking
  18. the.pos <- array(c(height, 100, -4, 0, 0), dim=c(1,5))
  19.  
  20. # initializes array to hold frame informaiton
  21. Z <- array(0, dim=c(height, width))
  22.  
  23. # draws road markers
  24. Z[c(95:105,295:305),] <- 0.5
  25. Z[c(195:205),(1:width)[(1:width + 10) %% 40 > 20]] <- 0.5
  26. Z.base <- Z # sets this as the starting state for each frame
  27.  
  28. # initializes array to hold gif information
  29. X <- array(0, dim=c(height, width, steps/2))
  30.  
  31. # draws people on the frame
  32. draw.people <- function(pos.array, Z) {
  33.   pos.array <- matrix(round(pos.array), ncol = 2)
  34.   for (i in 1:dim(pos.array)[1]) {
  35.     # gets position of person i
  36.     y.pos <- as.integer(pos.array[i, 1])
  37.     x.pos <- as.integer(pos.array[i, 2])
  38.    
  39.     # gets boundaries of person i's box
  40.     top <- max(c(y.pos-1, 1))
  41.     bottom <- min(c(y.pos+1), height)
  42.     left <- max(c(x.pos-1), 1)
  43.     right <- min(c(x.pos+1), height)
  44.    
  45.     # draws person i
  46.     Z[top:bottom,left:right] <- 1
  47.   }
  48.  
  49.   return(Z)
  50. }
  51.  
  52. # the potential each person sees
  53. main.der.potential <- function(x, state, t) {
  54.   if ((t - 15) %% 500 >= 400) { # if green light, the potential is zero
  55.     result <- 0
  56.   } else if (x >= height - 40) { # no potential to some point before the road
  57.     result <- 0
  58.   } else if (x >= (height - 100) && state == 0) { # increasing potential to curb
  59.     result <- (-x + (height - 40))/ 16
  60.   } else if (x >= (height - 300)) { # decreasing potential to opposite side
  61.     result <- -1
  62.   } else { # no potential on opposite side
  63.     result <- 0
  64.   }
  65.   return(result)
  66. }
  67.  
  68. # causes people to jaywalk
  69. change.state <- function(pos.array) {
  70.   for (i in 1:dim(pos.array)[1]) {
  71.     if (pos.array[i, 1] < (height - 70) && pos.array[i, 5] == 0) {
  72.       cur.prob <- (sum(abs(the.pos[, 1] - 250) <= 50) * 100 + 1) * 0.0008
  73.       pos.array[i, 5] <- as.integer(runif(1) < cur.prob)
  74.     }
  75.   }
  76.   return(pos.array)
  77. }
  78.  
  79. # move people depending on their speed
  80. move.people <- function(pos.array, t) {
  81.   pos.array <- matrix(pos.array, ncol = 5)
  82.   for (i in 1:dim(pos.array)[1]) {
  83.     y <- pos.array[i, 1]
  84.     x <- pos.array[i, 2]
  85.     dy <- pos.array[i, 3]
  86.     dx <- pos.array[i, 4]
  87.     dy <- dy + accel - fric * sign(dy) * sqrt(dx^2 + dy^2) +
  88.       main.der.potential(pos.array[i, 1], pos.array[i, 5], t)
  89.     dx <- dx - fric * sign(dx) * sqrt(dx^2 + dy^2)
  90.     y <- y + dy
  91.     x <- x + dx
  92.     pos.array[i, 1:4] <- c(y, x, dy, dx)
  93.   }
  94.   return(pos.array)
  95. }
  96.  
  97. # adds a new person
  98. add.person <- function(pos.array) {
  99.   taken <- round(pos.array[, 2])
  100.   taken <- c(taken, taken + 1, taken + 2, taken + 3, taken - 1 , taken - 2, taken - 3)
  101.   taken <- c(1, 2, 3, width - 2, width - 1, width, taken)
  102.   numpos <- length((1:width)[-taken])
  103.  
  104.   if (numpos > 50) {
  105.     new.y <- ((1:width)[-taken])[as.integer(round(runif(1) * numpos))]
  106.     pos.array <- rbind(pos.array, c(height, new.y, -4, 0, 0))
  107.   }
  108.  
  109.   return(pos.array)
  110. }
  111.  
  112. # remove people who have moved off the gif
  113. remove.past <- function(pos.array) {
  114.   pos.array <- matrix(pos.array[pos.array[, 1] > 0, ], ncol=5)
  115.   return(pos.array)
  116. }
  117.  
  118. # adds the green/red sign
  119. add.sign <- function(Z, t) {
  120.   if ((t - 15) %% 500 >= 400) {
  121.     Z[10:20, 180:190] <- 0.25
  122.   } else {
  123.     Z[20:30, 180:190] <- 0.75
  124.   }
  125.   return(Z)
  126. }
  127.  
  128. for (k in 1:steps) {        # iterate through the loop
  129.   Z <- Z.base # initializes the frame
  130.   Z <- draw.people(the.pos[, 1:2], Z) # draws people
  131.   Z <- add.sign(Z, k) # adds the sign
  132.   X[,,as.integer(k/2)] <- Z # store the frame
  133.   the.pos <- move.people(the.pos, k) # moves people for next frame
  134.   the.pos <- remove.past(the.pos) # remove people out of the frame
  135.   if ((dim(the.pos)[1] == 0) || runif(1) < 0.03) { # randomly or if no people
  136.     the.pos <- add.person(the.pos) # add a new person
  137.   }
  138.   the.pos <- change.state(the.pos) # try to change states
  139. }
  140. write.gif(X, "Jaywalking.gif", col=jet.colors, delay=8)
  141.  
  142. a <- 400:1
  143. b0 <- vapply(a, main.der.potential, double(1), t=200, state=0)
  144. c0 <- double(400)
  145. for (i in 2:400) {
  146.   c0[i] <- c0[i-1] + b0[i-1]
  147. }
  148.  
  149. b1 <- vapply(a, main.der.potential, double(1), t=200, state=1)
  150. c1 <- double(400)
  151. for (i in 2:400) {
  152.   c1[i] <- c1[i-1] + b1[i-1]
  153. }
  154.  
  155. png(filename="jaywalkpotential.png", width=400, height=400, units="px")
  156. plot(1:400,c1, type="l", ylim=c(-275,125), col="blue", ylab="Potential", xlab="Position", main="Potential vs. Position")
  157. lines(c0, col="red")
  158. abline(v=100, lty=2)
  159. abline(v=300, lty=2)
  160. legend("topright", legend=c("normal", "jaywalking"), fill=c("red", "blue"))
  161. dev.off()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement