Contents |
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'
Pacman
We'll define a Pacman shape using Constructive Geometry. The points satisfying
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&&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) \
&&atan2(y,x/2)>-PI*(1.0-z) ? "@":" ")};puts s}; \
sleep(0.03)end';reset # get cursor back :)
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
include Math
W,H=86,29
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
a = atan2((y-H/2)/5,(x-W/2)/10)
s[xi]=c[
vortex(r,a) % c.length]
}
puts s
}
Output:
@+ //@:++~@+::/@ @@%%/+::~~..~:+% ~:++++++++//%@ ~:+//%%%%%@@ .~::+%@ @@@@.+ :+:.@ +.+ ./++@~:.%:..~/@@@%/+:~......~:+%@ .~~~::::~~~:+/% ~+/%@ ..~:/ ~:~. .: +%%+~.+. +:+% .%: @@.+%%%+:.@@ .....~~~::::++//%@ .....~+% ~+%@@@@ ..~/ ://+~..+ +%@%+:/ ::/@%+ %/% ://:.%/+/% ..... @@@%%%@@ ~:+%%@@@@@ .~+@.:+/%%@ ... .~+ +%@@/+:/.+@@@%/ :+//~@///@.:~ /:~~:/@.... @@%%//++++/% ~+/%%@%%@@ ~:/@.~:+//% ~:++:~~~:/./@ . %/@~/@ @ :+:.@//+% @/~ .:%@ @%//++++:::+/@.:/%%%%%@ .:+/@ .~~::+/%.:/@@@%++/@~% ... @ :/@ :~.@%/+/%%/:.@@%@.+/%%/+:~...~:::::+% ~+%%%%@ .:/% ...~~~~~::/@~/ .~~. @@.+@ ..~..~+%@ ~.@%/++//+~ @@%%@.~:~. %///%@.~::::+% ~/%%%%@.:% ..~~~~~~~~~:+%.+@.~:::~..:/@ ..~.~:/%@ . %/++++:~. @%%%@ @%+:~..~:/@.:::::+%.:/%%%@~/@....~~:::+++/%@.+@.~:::::::+%@ ..~~~+/@ .@/++++:~. @%%%%%%/+:~.. .~+% ~:::~:+%.:///%~/ ...~:/%@ ..:/% .~::::::+/% .~~~~:+@ /::+++:~ %/%%%%%/+:~.. ~:/@ ~~~~~~+ :/+%~% ~+@.~:++++++++/%@ .~:::::+/%@~:~~~~+% %:.~+++:.%++/%%%/++:. .~:+/% ....: ++%:@ ~%.:++/////////%%@ .:+/++::+/@~++:~~:% + @.:+:~@+~~+/%%/+:.@%%%@@ @@@ .~+% ~.+@%@./ ~:+++//////////%@ .+%@@/+++/ :%%/:~:% ~%/@~:~ +.@ ~+//+~ %+:~:+/@@@ @@@@%%%//%.@.:% %~~::+/%@ . @@%%%%@.:% .. %//%.+ @+:+@ .//@~:~@: %@.:++:.%:~ .~:+/%%%%//+::~... .~~:++//%%//+~. .:% :++~ %%@~%.~.%+/ @++/@. /.%//% ~~.%:. @%%%@ .... @%/+:::~@ %+~ ~@%%%%@@@ @%/+::+%.://%/:. ./ :+: %@~ @+::/@%+ %/+/%@@%+~ @%%%%%%%%%///+++:./. @ +~~..@+~. @@%@ .:/%%%%+:~+@~+++. ./ %+:~://: %/+++///:~ @@%%%%%%%////+:.%:. +%++ :~~~. @%+:~.. .~:+/%%@%/+/@.:+/+~.:@ @+:~~::~ %/++++++:~. @%//+////++:.@/~...@~%//+ /:~~::~. %+~. ...~:+//%%@@%%@.~++/+::% @/:~~~~~ @%/+++++:~~.@/:~..... @/+~~.. %~@%%/+.%+:::::~.%+~....~:+/%@@@@@@@ ~:+///+/@. %+:~~~~. @/+:++++:~.@/~ %//++++::~~~~. /~ %%%%+~@/+:++:~ %+:~~:+/% . @@@@ .:+/////@ ~ @/:~~~~~. %:~~~:+::~ /~@/+::~~~~~~~~. %+. @@@%/:.%++++::.@%//%@ ~:::~ @@@ .:+/////% .: %/~..~~~.@+. @ .~~~ %: /+:::~~~~~. @/:~ @@@@%/: %+++++::~..~:+/%@%+~ @@ .:%@%///%@.:: @%+. ~~. %:@///%@ @%+.@/++::~. @%/:~. @@@@@%+~@/+++++++//%@@ .. %+. .:/ . %//%@.++: @ @%~@%@ .. /.%:~~::+++~.@%//+:.@%+~. @@@@@@%+:.@%/++//%%@@ ..~~. %:~~:% ~:~ %/% ~/%+: /% @/./++%@ @+./:........ @@%%/:.@/:. @%/+~. @@@@@ ...~~~.@///@.+//+.@%@.+@@/:: %++@@@+ +~~:/%/: /:~... @%/:.%+:~...... @%//++++:::~~~~~. .:/%@@/~ @.:@..%++/ ./~~+%%+ +. .::~ %+:~....... @%+:.@/+::::::::::~.. %/+:~~~~~~~:/%@ @/:.~+@~:~@/+%~ /.+. .+/+ +. @@ . @/+:~. @@@@%%%/+:~. @%////////+:~.@/:~~~~::++/%@ @%++/ :+/: %% + ++./ @@ ~~./~ @@@@@@@%//+:.@%+:~~.. @@%%////////+~.@/+::~::++/%@@ @%%@.:/%/: @ + ~.
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 :pyf <filename of this program>
#!/usr/bin/env python
# coding: iso-8859-1
from vim import *
from math import *
from re import *
# CONFIGURATION ___________________________________________________________________________________
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
# EXAMPLE FUNCTIONS _______________________________________________________________________________
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
# MAIN PROGRAM ____________________________________________________________________________________
combination = lambda x,y : shade(circles(0,x,y)/4.+blob(0,x,y)*0.5+0.3,x,y)
beautify(combination)
#clear() # uncomment this to remove all beautification
See also the page on Python Lambda Forms.
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.