j0h

sinewave-text

j0h
Jan 4th, 2026
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.76 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import math
  3. from typing import List, Tuple
  4. '''
  5. Ok i gotta think about this more or something.
  6. https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
  7. '''
  8.  
  9. def swta(
  10.     raw_text: str,
  11.     amplitude: int = 5,
  12.     period: int = 48,
  13.     center_char: str = " ",
  14.     empty: str = " ",
  15.     oversample: int = 8,
  16.     compact: bool = False,
  17.     show_text_spaces_as: str | None = " ",  # set None to keep literal spaces (but compact will remove them)
  18. ) -> None:
  19.     import math
  20.  
  21.     if not raw_text:
  22.         print("(empty string)")
  23.         return
  24.  
  25.     # If we plan to remove ALL background spaces, make literal spaces in the text visible first
  26.     if compact and show_text_spaces_as is not None:
  27.         raw_text = raw_text.replace(" ", show_text_spaces_as)
  28.  
  29.     n = len(raw_text)
  30.     if n == 0:
  31.         return
  32.  
  33.     k = 2 * math.pi / (period * oversample)
  34.     sub_steps = max(n * oversample * 2, period * oversample * 2)
  35.  
  36.     y_sub = [amplitude * math.sin(k * i) for i in range(sub_steps + 1)]
  37.  
  38.     s = [0.0]
  39.     for i in range(sub_steps):
  40.         dy = y_sub[i + 1] - y_sub[i]
  41.         s.append(s[-1] + math.sqrt(1.0 + dy * dy))
  42.  
  43.     total_len = s[-1]
  44.     if total_len == 0:
  45.         print(raw_text)
  46.         return
  47.  
  48.     targets = [total_len * (i / (n - 1)) if n > 1 else 0.0 for i in range(n)]
  49.  
  50.     idxs = []
  51.     j = 0
  52.     for t in targets:
  53.         while j < len(s) - 1 and s[j] < t:
  54.             j += 1
  55.         idxs.append(j)
  56.  
  57.     cols = []
  58.     last_c = -1
  59.     for sub_i in idxs:
  60.         c = int(round(sub_i / oversample))
  61.         if c <= last_c:
  62.             c = last_c + 1
  63.         cols.append(c)
  64.         last_c = c
  65.  
  66.     width = cols[-1] + 1
  67.     offsets = [int(round(y_sub[sub_i])) for sub_i in idxs]
  68.  
  69.     min_y = min(offsets)
  70.     max_y = max(offsets)
  71.     height = max_y - min_y + 1
  72.     zero_row = -min_y
  73.  
  74.     grid = [[empty for _ in range(width)] for _ in range(height)]
  75.  
  76.     if center_char != " ":
  77.         for x in range(width):
  78.             grid[zero_row][x] = center_char
  79.  
  80.     for ch, x, off in zip(raw_text, cols, offsets):
  81.         r = zero_row - off
  82.         if 0 <= r < height and 0 <= x < width:
  83.             grid[r][x] = ch
  84.  
  85.     for row in grid:
  86.         line = "".join(row)
  87.         if compact:
  88.             # Remove ALL background filler characters
  89.             line = line.replace(empty, "")
  90.         else:
  91.             # Normal: keep spacing, but don't print trailing background
  92.             line = line.rstrip(empty)
  93.         if line:
  94.             print(line)
  95.     print()
  96.  
  97.  
  98. if __name__ == "__main__":
  99.     text1 = r"Its a shame, I have nothing to say, when I just want to warp my words"
  100.     swta(text1, amplitude=5, period=48, center_char=" ")
  101.     swta(text1, amplitude=5, period=48, center_char=" ", compact=True)
  102.  
Advertisement
Add Comment
Please, Sign In to add comment