Advertisement
spytheman123

A spinning donut, shown in a terminal. Written in V.

Sep 4th, 2023
2,030
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 2.01 KB | Source Code | 0 0
  1. module main
  2.  
  3. import math
  4. import term
  5. import strings
  6. import time { sleep }
  7.  
  8. const ascii_luminance_table = '.,-~:;=!*#$@'
  9.  
  10. [direct_array_access]
  11. fn render_donut(columns int, lines int, a f64, b f64) {
  12.     theta_spacing, phi_spacing := 0.07, 0.02
  13.  
  14.     r1, r2, k2 := 1, 2, 5
  15.     k1 := columns * k2 * 2 / (20 * (r1 + r2))
  16.  
  17.     cos_a, sin_a := math.cos(a), math.sin(a)
  18.     cos_b, sin_b := math.cos(b), math.sin(b)
  19.  
  20.     mut output := [][]rune{len: columns, init: []rune{len: lines, init: ` `}}
  21.     mut z_buffer := [][]f64{len: columns, init: []f64{len: lines, init: 0}}
  22.  
  23.     for theta := f64(0); theta < 2 * math.pi; theta += theta_spacing {
  24.         cos_theta, sin_theta := math.cos(theta), math.sin(theta)
  25.  
  26.         for phi := f64(0); phi < 2 * math.pi; phi += phi_spacing {
  27.             cos_phi, sin_phi := math.cos(phi), math.sin(phi)
  28.  
  29.             circle_x, circle_y := r2 + r1 * cos_theta, r1 * sin_theta
  30.             x := circle_x * (cos_b * cos_phi + sin_a * sin_b * sin_phi) - circle_y * cos_a * sin_b
  31.             y := circle_x * (sin_b * cos_phi - sin_a * cos_b * sin_phi) + circle_y * cos_a * cos_b
  32.             z := k2 + cos_a * circle_x * sin_phi + circle_y * sin_a
  33.             ooz := 1 / z
  34.  
  35.             xp := int(columns / 2 + k1 * ooz * x)
  36.             yp := int(lines / 2 - k1 * ooz * y)
  37.  
  38.             l := cos_phi * cos_theta * sin_b - cos_a * cos_theta * sin_phi - sin_a * sin_theta +
  39.                 cos_b * (cos_a * sin_theta - cos_theta * sin_a * sin_phi)
  40.  
  41.             if l > 0 {
  42.                 if xp < 0 || yp < 0 || xp >= columns || yp >= lines {
  43.                     continue
  44.                 }
  45.                 if ooz > z_buffer[int(xp)][int(yp)] {
  46.                     z_buffer[xp][yp] = ooz
  47.                     luminance_index := int(l * 8)
  48.                     output[xp][yp] = ascii_luminance_table[luminance_index]
  49.                 }
  50.             }
  51.         }
  52.     }
  53.     mut sb := strings.new_builder(lines*columns)
  54.     print('\x1b[H')
  55.     for j := 0; j < lines; j++ {
  56.         for i := 0; i < columns; i++ {
  57.             sb.write_rune(output[i][j])
  58.         }
  59.         sb.write_rune(`\n`)
  60.     }
  61.     print(sb.str())
  62. }
  63.  
  64. fn main() {
  65.     term.clear()
  66.     columns, lines := 80, 25
  67.     mut a, mut b := f64(0), f64(0)
  68.     for {
  69.         render_donut(columns, lines, a, b)
  70.         a += 0.05
  71.         b += 0.07
  72.         sleep(15)
  73.     }
  74. }
  75.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement