ASCII Art

Simple Stuff
ruby -e'd="#";c="\033[1;3";a=(c+"1m"+d*20+c+"7m"+d*14+c+"1m"+d*40+"\n")*10;b=c+"7m"+(d*74+"\n")*6;puts a+b+a'

Constructive Geometry
Pacman

We'll define a Pacman shape using Constructive Geometry. The points satisfying


 * $$x^2+y^2<11^2 \quad \land \quad -\frac{4}{5}\pi < \textrm{atan2}(y,x) < \frac{4}{5}\pi \quad \land \quad x^2+(y+6)^2>1$$

are part of the Pacman. The following Ruby one-liner draws it (just paste directly into terminal):

ruby -e'include Math;(-10..10).each{|y|s="";\ (-14..14).each{|x| s << (x**2+y**2<11**2   \ && atan2(y,x)-PI*0.8    \ && x**2+(y+6)**2>1 ? "@":" ")*2};puts s}' Here's an animated version:

ruby -e'include Math; \ print "\033[2J\033[1;33m\033[?25l";z=0.0;dz=0.05;\ while(true)do z+=dz;dz=-dz if(z<0.0||z>0.2);    \ print "\033[0;0f";(-10..10).each{|y|s="";       \ (-39..39).each{|x| s << ((x/2)**2+y**2<11**2    \ && atan2(y,x/2)-PI*(1.0-z) ? "@":" ")};puts s};  \ sleep(0.03)end';reset # get cursor back :)

Short Unreadable Beauty
Here's a short example that creates a beautiful pattern: ruby -e'include Math;(-7..30).each{|y|s="";\ (26..100).each{|x|s<<" .,:+*%xX08@"[ \ ((sin(x/8.0)+2+sin(y*x/2.0))**      \ (sin(y/7.0)+1)*12/16.0)]};puts s}' Or in Python: from math import * for y in range(-7,30): line = "" for x in range(26,100): line+=" .,:+*%xX08@"[int((sin(x/8.)+2+sin(y*x/2.))**(sin(y/7.)+1)*12/(16.))] print line

Flower
Below is an example of a polar shape that uses modular numbers (ascii table loops as the input number gets higher).

An interesting aspect of it is the character table used:

This table yields an uneven and messy shading, similar to that of a pencil drawing. include Math W,H=400,170 SCALE=0.1 s=" "*(W+1);c=" .~:+/%@"

def flower(r,a) (sin(a*10)*2 + sin(r)*1.0) end def circle(r,a) r end def thing(r,a) a * 18 end def spiral(r,a) thing(r,a) + circle(r,a) end def vortex(r,a) (spiral(r,a+sin(r)/10) + flower(r,a+sin(r)/10)) end

(0..H).each{|yi| (0..W).each{|xi| x,y = xi.to_f,yi.to_f r = (((x-W/2)/10)**2+((y-H/2)/5)**2) * SCALE a = atan2((y-H/2)/5,(x-W/2)/10) s[xi]=c[

vortex(r,a) % c.length]

} puts s } Output: 

Beautification With Comments


The next example is a bit alternative. It uses the Python interface to Vim, so you'll have to load it into Vim (which has to have Python support compiled in). Then, to create the "beautification" you should execute the command

Source Code
from vim import * from math import * from re  import * aa       = " .,:+*&%#08@"  # ASCII-art character set rmargin  = 1               # Distance from gfx to right edge of window tmargin  = 16              # Distance from gfx to top edge of buffer bmargin  = 0               # Distance from gfx to bottom edge of buffer w        = current.window.width b        = current.buffer lenlist  = range(len(b))   # FIXME: This looks stupid. How do I declare a list without this hack? smoothing = 24             # Smoothing on left edge of gfx def clear:    # Remove the results of beautify for l in range(len(b)): pattern = compile(" *#[" + aa + "]*$") # all lines that end with commented ASCII-art chars b[l] = sub(pattern, "", b[l])         # remove them def spaces(l):  # Return an indentation value interpolated from current indentation values sum = 0 for n in range(-smoothing/2,smoothing/2+1):      # sum the lengths of nearby lines if  l+n < 0       : sum += lenlist[0]        # above the top of the buffer elif l+n >= len(b) : sum += lenlist[len(b)-1] # below the bottom of the buffer else              : sum += lenlist[l+n] return max(1, int(sum / (smoothing+1) + w/4 - len(b[l])) ) def beautify(f): # add comments with ASCII art pattern at the end of every line clear for l in range(len(b)): lenlist[l] = len(b[l]) # save all old line lengths for l in range(tmargin,len(b)-bmargin): # do we have space to draw gfx on this line? if w-rmargin > len(b[l]): b[l] += " " * spaces(l) + "# " for x in range(len(b[l]),w-rmargin):  # from left edge of text to right margin col = f(x,l)                      # apply function if  (col < 0)   : col = 0         # cut extreme colour values elif (col > .99) : col = 0.99 b[l] += aa[ int( col * len(aa) ) ] # ASCII artify colour shade    = lambda col,x,y: col - float(w-x) / w righthalf = lambda colf,x,y: (x>(w/2)) * col wave   = lambda col,x,y: col + sin( y * .2 ) / 10 + .5 int2   = lambda col,x,y: col + (x * y) % 40 / 40. - .2 stripe = lambda col,x,y: col + (x + y) % 10 / 10. - .2 circles = lambda col,x,y: col + (((x-2*w/3)**2 + (y*1.8-43)**2)**.5) % 8 < 4 int1   = lambda col,x,y: col + ( sin( x / 8.) + 2 + sin( y * x / 2.)) ** ( sin( y / 7. ) + 1 ) / 16. blob   = lambda col,x,y: col + ( sin( x * .5 + sin(  x * .23 + y * .21 ))                       + sin( y * .5 + sin( -x * .23 + y * .21 ))) / 2. + .2 combination = lambda x,y : shade(circles(0,x,y)/4.+blob(0,x,y)*0.5+0.3,x,y) beautify(combination)
 * 1) !/usr/bin/env python
 * 2) coding: iso-8859-1
 * 1) CONFIGURATION ___________________________________________________________________________________
 * 1) EXAMPLE FUNCTIONS _______________________________________________________________________________
 * 1) MAIN PROGRAM ____________________________________________________________________________________
 * 1) clear # uncomment this to remove all beautification

See also the page on Python Lambda Forms.

Raytracer


This is the Python version of my JayTracer. I was rendering some stuff in POV-Ray on my 233 MHz machine, and was reading the "bootstrapping raytracer" part of the POV-ray tutorial. It explained the basic raytracing algorithm, and I wanted to make my own. Later (much later!) that night/morning, the Python version was done, and produced the output on the right.