Yin and yang: Difference between revisions
(→{{header|Tcl}}: Add link to file (which is about to be created)) |
m (→{{header|Tcl}}: sizing) |
||
Line 239: | Line 239: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
[[File:yinyang-tcl.gif|frame|Output of this Tcl program]] |
[[File:yinyang-tcl.gif|frame|50x50px|Output of this Tcl program]] |
||
{{libheader|Tk}} |
{{libheader|Tk}} |
||
<lang tcl>package require Tcl 8.5 |
<lang tcl>package require Tcl 8.5 |
Revision as of 23:13, 18 April 2011
Create a function that given a variable representing size, generates a Yin and yang also known as a Taijitu symbol scaled to that size.
Generate and display the symbol generated for two different (small) sizes.
D
<lang d>import std.stdio, std.string, std.algorithm ;
enum { Void = 0, Yan = 1, Yin = 2, I = 3} ; enum Tiles = [" ","·","#","?"] ;
alias int delegate(int) Draw ;
struct Board { // a square board
immutable int scale ; immutable int size ; int[][] pix ; this(int s) { scale = s ; size = s*12 ; pix = new int[][](size + 1,size + 1) ; } alias pix this ; static string str(int v) { return Tiles[(v % 4)] ; } string toString() { string[] s ; foreach( r ; pix) s ~= reduce!"a~b"(map!str(r)) ; return s.join("\n") ; } void drawCircle(int cx, int cy, int cr, Draw action) { auto rr = (cr*scale)^^2 ; foreach(y, ref r ; pix) foreach( x , ref v ; r) { auto dx = x - cx*scale ; auto dy = y - cy*scale ; if(dx^^2 + dy^^2 <= rr) v = action(x) ; } } Board yanYin() { foreach(r ; pix) // clear r[] = 0 ; drawCircle(6,6,6, (int x) { return (x < 6*scale) ? Yan : Yin ; }) ; drawCircle(6,3,3, (int x) { return Yan ; } ) ; drawCircle(6,9,3, (int x) { return Yin ; } ) ; drawCircle(6,9,1, (int x) { return Yan ; } ) ; drawCircle(6,3,1, (int x) { return Yin ; } ) ; return this ; }
}
void main(string[] args) {
writeln(Board(2).yanYin) ; writeln(Board(1).yanYin) ;
}</lang> Output:
· ········# ···········## ·············## ········#·····### ········###····#### ········#####····#### ·········###····##### ···········#·····###### ·················###### ················####### ···············######## ············############# ········############### ·······################ ······################# ······#####·########### ·····####···######### ····####·····######## ····####···######## ···#####·######## ··############# ··########### ·######## # · ······# ····#··## ····###··## ·····#··### ········### ······####### ···######## ···##·##### ··##···#### ··##·#### ·###### #
J
Based on the Python implementation:
<lang j>yinyang=:3 :0
radii=. y*1 3 6 ranges=. i:each radii squares=. ,"0/~each ranges circles=. radii ([ >: +/"1&.:*:@])each squares cInds=. ({:radii) +each circles #&(,/)each squares
M=. ' *.' {~ circles (* 1 + 0 >: {:"1)&(_1&{::) squares offset=. 3*y,0 M=. '*' ((_2 {:: cInds) <@:+"1 offset)} M M=. '.' ((_2 {:: cInds) <@:-"1 offset)} M M=. '.' ((_3 {:: cInds) <@:+"1 offset)} M M=. '*' ((_3 {:: cInds) <@:-"1 offset)} M
)</lang>
Note: although the structure of this program is based on the python implementation, some details are different. In particular, in the python implementation, the elements of squares and circles have no x,y structure -- they are flat list of coordinates.
Here, the three squares
are each 3 dimensional arrays. The first two dimensions correspond to the x and y values and the last dimension is 2 (the first value being the y coordinate and the second being the x coordinate -- having the dimensions as y,x pairs like this works because in J the first dimension of a matrix is the number of rows and the second dimension is the number of columns).
Also, the three elements in the variable circles
are represented by 2 dimensional arrays. The dimensions correspond to x and y values and the values are bits -- 1 if the corresponding coordinate pair in squares is a member of the circle and 0 if not.
Finally, the variable cInds
corresponds very closely to the variable circles
in the python code. Except, instead of having y and x values, cInds has indices into M
. In other words, I added the last value from radii to the y and x values. In other words, instead of having values in the range -18..18, I would have values in the range 0..36 (but replace 18 and 36 with whatever values are appropriate).
Example use:
<lang> yinyang 1
. ......* ....*..** ....***..** .....*..*** ........***
.......******
...******** ...**.***** ..**...**** ..**.**** .****** * yinyang 2 . ........* ...........** .............** ........*.....*** ........***....**** ........*****....**** .........***....***** ...........*.....****** .................****** ................******* ...............********
.............************
........*************** .......**************** ......***************** ......*****.*********** .....****...********* ....****.....******** ....****...******** ...*****.******** ..************* ..*********** .******** * </lang>
Python
For positive integer n > 0, the following generates an ASCII representation of the Yin yang symbol.
<lang python>import math def yinyang(n=3): radii = [i * n for i in (1, 3, 6)] ranges = [list(range(-r, r+1)) for r in radii] squares = [[ (x,y) for x in rnge for y in rnge] for rnge in ranges] circles = [[ (x,y) for x,y in sqrpoints if math.hypot(x,y) <= radius ] for sqrpoints, radius in zip(squares, radii)] m = {(x,y):' ' for x,y in squares[-1]} for x,y in circles[-1]: m[x,y] = '*' for x,y in circles[-1]: if x>0: m[(x,y)] = '·' for x,y in circles[-2]: m[(x,y+3*n)] = '*' m[(x,y-3*n)] = '·' for x,y in circles[-3]: m[(x,y+3*n)] = '·' m[(x,y-3*n)] = '*' return '\n'.join(.join(m[(x,y)] for x in reversed(ranges[-1])) for y in ranges[-1])</lang>
- Sample generated symbols for
n = 2
andn = 3
>>> print(yinyang(2)) · ········* ···········** ·············** ········*·····*** ········***····**** ········*****····**** ·········***····***** ···········*·····****** ·················****** ················******* ···············******** ·············************ ········*************** ·······**************** ······***************** ······*****·*********** ·····****···********* ····****·····******** ····****···******** ···*****·******** ··************* ··*********** ·******** * >>> print(yinyang(1)) · ······* ····*··** ····***··** ·····*··*** ········*** ·······****** ···******** ···**·***** ··**···**** ··**·**** ·****** * >>>
Tcl
![](http://static.miraheze.org/rosettacodewiki/1/1b/Yinyang-tcl.gif)
<lang tcl>package require Tcl 8.5 package require Tk
namespace import tcl::mathop::\[-+\] ;# Shorter coordinate math proc yinyang {c x y r {colors {white black}}} {
lassign $colors a b set tt [expr {$r * 2 / 3.0}] set h [expr {$r / 2.0}] set t [expr {$r / 3.0}] set s [expr {$r / 6.0}] $c create arc [- $x $r] [- $y $r] [+ $x $r] [+ $y $r] \
-fill $a -outline {} -extent 180 -start 90
$c create arc [- $x $r] [- $y $r] [+ $x $r] [+ $y $r] \
-fill $b -outline {} -extent 180 -start 270
$c create oval [- $x $h] [- $y $r] [+ $x $h] $y \
-fill $a -outline {}
$c create oval [- $x $h] [+ $y $r] [+ $x $h] $y \
-fill $b -outline {}
$c create oval [- $x $s] [- $y $tt] [+ $x $s] [- $y $t] \
-fill $b -outline {}
$c create oval [- $x $s] [+ $y $tt] [+ $x $s] [+ $y $t] \
-fill $a -outline {} }
pack [canvas .c -width 300 -height 300 -background gray50] yinyang .c 110 110 90 yinyang .c 240 240 40</lang>