Yin and yang: Difference between revisions
m →{{header|Perl}}: wrap long lines |
|||
Line 838: | Line 838: | ||
print "<g transform='rotate($opt{angle}, $cx, $cy)'>" |
print "<g transform='rotate($opt{angle}, $cx, $cy)'>" |
||
if |
if $opt{angle}; |
||
if ($opt{flip}) { ($c, $w) = ($w, $c) }; |
if ($opt{flip}) { ($c, $w) = ($w, $c) }; |
Revision as of 01:07, 6 November 2011
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
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.
Asymptote
<lang asymptote>unitsize(1 inch);
fill(scale(6)*unitsquare, invisible);
picture yinyang(pair center, real radius) {
picture p; fill(p, unitcircle, white); fill(p, arc(0, S, N) -- cycle, black); fill(p, circle(N/2, 1/2), white); fill(p, circle(S/2, 1/2), black); fill(p, circle(N/2, 1/5), black); fill(p, circle(S/2, 1/5), white); draw(p, unitcircle, linewidth((1/32) * inch) + gray(0.5)); return shift(center) * scale(radius) * p;
}
add(yinyang((1 + 1/4, 4 + 3/4), 1)); add(yinyang((3 + 3/4, 2 + 1/4), 2));</lang>
ALGOL 68
<lang algol68>INT scale x=2, scale y=1; CHAR black="#", white=".", clear=" ";
PROC print yin yang = (REAL radius)VOID:(
PROC in circle = (REAL centre x, centre y, radius, x, y)BOOL: (x-centre x)**2+(y-centre y)**2 <= radius**2;
PROC (REAL, REAL)BOOL in big circle = in circle(0, 0, radius, , ), in white semi circle = in circle(0, +radius/2, radius/2, , ), in small black circle = in circle(0, +radius/2, radius/6, , ), in black semi circle = in circle(0, -radius/2, radius/2, , ), in small white circle = in circle(0, -radius/2, radius/6, , );
FOR sy FROM +ROUND(radius * scale y) BY -1 TO -ROUND(radius * scale y) DO FOR sx FROM -ROUND(radius * scale x) TO +ROUND(radius * scale x) DO REAL x=sx/scale x, y=sy/scale y; print( IF in big circle(x, y) THEN IF in white semi circle(x, y) THEN IF in small black circle(x, y) THEN black ELSE white FI ELIF in black semi circle(x, y) THEN IF in small white circle(x, y) THEN white ELSE black FI ELIF x < 0 THEN white ELSE black FI ELSE clear FI ) OD; print(new line) OD
);
main:(
print yin yang(17); print yin yang(8)
)</lang> Output:
. ....................### ...........................###### ................................####### ....................................####### ........................................######### .......................#####..............######### .......................#########............########### .......................###########...........############ .........................###########...........############## ..........................#########............############## .............................#####..............############### ................................................################# ................................................################### ..............................................##################### ............................................####################### ..........................................######################### ...................................################################## .........................########################################## .......................############################################ .....................############################################## ...................################################################ .................################################################ ...............##############.....############################# ..............############.........########################## ..............###########...........######################### ............###########...........####################### ...........############.........####################### .........##############.....####################### .........######################################## .......#################################### .......################################ ......########################### ...#################### # . .............## .................#### ...........###......##### ...........#####......##### .............###......####### ......................######### .....................########## .................################ ..........##################### .........###################### .......######...############# .....######.....########### .....######...########### ....################# ..############# #
BBC BASIC
![](http://static.miraheze.org/rosettacodewiki/c/cb/Yinyangbbc.gif)
<lang bbcbasic> PROCyinyang(200, 200, 100)
PROCyinyang(700, 400, 300) END DEF PROCyinyang(xpos%, ypos%, size%) CIRCLE xpos%, ypos%, size% LINE xpos%, ypos%+size%, xpos%, ypos%-size% FILL xpos%+size%/2, ypos% CIRCLE FILL xpos%, ypos%-size%/2, size%/2+2 GCOL 15 CIRCLE FILL xpos%, ypos%+size%/2, size%/2+2 CIRCLE FILL xpos%, ypos%-size%/2, size%/6+2 GCOL 0 CIRCLE FILL xpos%, ypos%+size%/2, size%/6+2 CIRCLE xpos%, ypos%, size% ENDPROC</lang>
C
Writes to stdout a SVG file with two yin-yangs (no, it's really just that big):
<lang C>#include <stdio.h>
void draw_yinyang(int trans, double scale) { printf("<use xlink:href='#y' transform='translate(%d,%d) scale(%g)'/>", trans, trans, scale); }
int main() { printf( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n" " 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n" "<svg xmlns='http://www.w3.org/2000/svg' version='1.1'\n" " xmlns:xlink='http://www.w3.org/1999/xlink'\n" " width='30' height='30'>\n" " <defs><g id='y'>\n" " <circle cx='0' cy='0' r='200' stroke='black'\n" " fill='white' stroke-width='1'/>\n" " <path d='M0 -200 A 200 200 0 0 0 0 200\n" " 100 100 0 0 0 0 0 100 100 0 0 1 0 -200\n" " z' fill='black'/>\n" " <circle cx='0' cy='100' r='33' fill='white'/>\n" " <circle cx='0' cy='-100' r='33' fill='black'/>\n" " </g></defs>\n"); draw_yinyang(20, .05); draw_yinyang(8, .02); printf("</svg>"); return 0; }</lang>
D
<lang d>import std.stdio, std.string, std.algorithm, std.array;
struct SquareBoard {
enum W : char { Void=' ', Yan='.', Yin='#', I='?' };
immutable int scale; W[][] pix;
this(int s) { scale = s; pix = new W[][](s * 12 + 1, s * 12 + 1); }
string toString() { auto rows = map!q{ (cast(char[])a).idup }(pix); return join(array(rows), "\n"); }
void drawCircle(Draw)(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); } }
SquareBoard yanYin() { foreach (r; pix) // clear r[] = W.Void; drawCircle(6, 6, 6, (int x){ return (x < 6*scale) ? W.Yan : W.Yin; }); drawCircle(6, 3, 3, (int x){ return W.Yan; }); drawCircle(6, 9, 3, (int x){ return W.Yin; }); drawCircle(6, 9, 1, (int x){ return W.Yan; }); drawCircle(6, 3, 1, (int x){ return W.Yin; }); return this; }
}
void main() {
writeln(SquareBoard(2).yanYin()); writeln(SquareBoard(1).yanYin());
}</lang> Output:
· ········# ···········## ·············## ········#·····### ········###····#### ········#####····#### ·········###····##### ···········#·····###### ·················###### ················####### ···············######## ············############# ········############### ·······################ ······################# ······#####·########### ·····####···######### ····####·····######## ····####···######## ···#####·######## ··############# ··########### ·######## # · ······# ····#··## ····###··## ·····#··### ········### ······####### ···######## ···##·##### ··##···#### ··##·#### ·###### #
Delphi
<lang delphi>procedure TForm1.ButtonCreateClick(Sender: TObject);
begin
DrawYinAndYang(StrToInt(EditSize.Text), Canvas, GetClientRect);
end;
procedure DrawYinandYang(size: Word; DrawArea: TCanvas; R: TRect); begin
DrawArea.Brush.Color := clGray; DrawArea.FillRect(R); DrawArea.Brush.Color := clwhite; DrawArea.Pen.Color := clwhite; DrawArea.Pie(10, 10, 10 + size, 10 + size, 10 + (size div 2), 10, 10 + (size div 2), 10 + size); DrawArea.Brush.Color := clblack; DrawArea.Pen.Color := clblack; DrawArea.Pie(10, 10, 10 + size, 10 + size, 10 + (size div 2), 10 + size, 10 + (size div 2), 10); DrawArea.Brush.Color := clwhite; DrawArea.Pen.Color := clwhite; DrawArea.Ellipse(10 + (size div 4), 10, 10 + 3 * (size div 4),10 + (size div 2)); DrawArea.Brush.Color := clblack; DrawArea.Pen.Color := clblack; DrawArea.Ellipse(10 + (size div 4), 10 + (size div 2), 10 + 3 * (size div 4), 10 + size); DrawArea.Brush.Color := clwhite; DrawArea.Pen.Color := clwhite; DrawArea.Ellipse(10 + 7 * (size div 16), 10 + 11 * (size div 16), 10 + 9 * (size div 16),10 + 13 * (size div 16)); DrawArea.Brush.Color := clblack; DrawArea.Pen.Color := clblack; DrawArea.Ellipse(10 + 7 * (size div 16), 10 + 3 * (size div 16), 10 + 9 * (size div 16),10 + 5 * (size div 16));
end;</lang>
DWScript
<lang delphi> type
TColorFuncX = function (x : Integer) : Integer;
type
TSquareBoard = class Scale : Integer; Pix : array of array of Integer;
constructor Create(aScale : Integer); begin Scale := aScale; Pix := new Integer[aScale*12+1, aScale*12+1]; end;
method Print; begin var i, j : Integer; for i:=0 to Pix.High do begin for j:=0 to Pix.High do begin case Pix[j, i] of 1 : Print('.'); 2 : Print('#'); else Print(' '); end; end; PrintLn(); end; end;
method DrawCircle(cx, cy, cr : Integer; color : TColorFuncX); begin var rr := Sqr(cr*Scale); var x, y : Integer; for x := 0 to Pix.High do begin for y := 0 to Pix.High do begin if Sqr(x-cx*Scale)+Sqr(y-cy*Scale)<=rr then Pix[x, y] := color(x); end; end; end;
method ColorHalf(x : Integer) : Integer; begin if (x<6*Scale) then Result:=1 else Result:=2; end;
method ColorYin(x : Integer) : Integer; begin Result:=2; end;
method ColorYang(x : Integer) : Integer; begin Result:=1; end;
method YinYang; begin DrawCircle(6, 6, 6, ColorHalf); DrawCircle(6, 3, 3, ColorYang); DrawCircle(6, 9, 3, ColorYin); DrawCircle(6, 9, 1, ColorYang); DrawCircle(6, 3, 1, ColorYin); end;
end;
var sq := new TSquareBoard(2); sq.YinYang; sq.Print;
sq := new TSquareBoard(1); sq.YinYang; sq.Print; </lang> Output:
. ........# ...........## .............## ........#.....### ........###....#### ........#####....#### .........###....##### ...........#.....###### .................###### ................####### ...............######## ............############# ........############### .......################ ......################# ......#####.########### .....####...######### ....####.....######## ....####...######## ...#####.######## ..############# ..########### .######## # . ......# ....#..## ....###..## .....#..### ........### ......####### ...######## ...##.##### ..##...#### ..##.#### .###### #
Go
There are some emerging third-party 2D graphics libraries for Go; meanwhile, here is an SVG solution using only standard libraries. <lang go>package main
import (
"fmt" "os" "template"
)
var tmpl = `<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="yy" viewBox="0 0 200 200"> <circle stroke="black" stroke-width="2" fill="white"
cx="100" cy="100" r="99" />
<path fill="black"
d="M100 100 a49 49 0 0 0 0 -98 v-1 a99 99 0 0 1 0 198 v-1 a49 49 0 0 1 0 -98" />
<circle fill="black" cx="100" cy="51" r="17" /> <circle fill="white" cx="100" cy="149" r="17" /> </symbol> Template:Range .<use xlink:href="#yy"
x="Template:.X" y="Template:.Y" width="Template:.Sz" height="Template:.Sz"/>
Template:End</svg> `
// structure specifies position and size to draw symbol type xysz struct {
X, Y, Sz int
}
// example data to specify drawing the symbol twice, // with different position and size. var yys = []xysz{
{20, 20, 100}, {140, 30, 60},
}
func main() {
xt := template.New("") template.Must(xt.Parse(tmpl)) f, err := os.Create("yy.svg") if err != nil { fmt.Println(err) return } if err := xt.Execute(f, yys); err != nil { fmt.Println(err) } f.Close()
}</lang>
Haskell
This program uses the diagrams package to produce the Yin and Yang image. The package implements an embedded DSL for producing vector graphics. Depending on the command-line arguments, the program can generate SVG, PNG, PDF or PostScript output. The sample output was created with the command yinyang -o YinYang-Haskell.svg. <lang haskell>{-# LANGUAGE NoMonomorphismRestriction #-}
import Diagrams.Prelude import Diagrams.Backend.Cairo.CmdLine
yinyang = lw 0 $
perim # lw 0.003 <> torus white black # xform id <> torus black white # xform negate <> clipBy perim base where perim = arc 0 (360 :: Deg) # scale (1/2) torus c c' = circle (1/3) # fc c' <> circle 1 # fc c xform f = translateY (f (1/4)) . scale (1/4) base = rect (1/2) 1 # fc white ||| rect (1/2) 1 # fc black
main = defaultMain $
pad 1.1 $ beside (2,-1) yinyang (yinyang # scale (1/4))</lang>
Icon and Unicon
<lang Icon>link graphics
procedure main() YinYang(100) YinYang(40,"blue","yellow","white") WDone() # quit on Q/q end
procedure YinYang(R,lhs,rhs,bg) # draw YinYang with radius of R pixels and ... /lhs := "white" # left hand side /rhs := "black" # right hand side /bg := "grey" # background
wsize := 2*(C := R + (margin := R/5))
W := WOpen("size="||wsize||","||wsize,"bg="||bg) | stop("Unable to open Window") WAttrib(W,"fg="||lhs) & FillCircle(W,C,C,R,+dtor(90),dtor(180)) # main halves WAttrib(W,"fg="||rhs) & FillCircle(W,C,C,R,-dtor(90),dtor(180)) WAttrib(W,"fg="||lhs) & FillCircle(W,C,C+R/2,R/2,-dtor(90),dtor(180)) # sub halves WAttrib(W,"fg="||rhs) & FillCircle(W,C,C-R/2,R/2,dtor(90),dtor(180)) WAttrib(W,"fg="||lhs) & FillCircle(W,C,C-R/2,R/8) # dots WAttrib(W,"fg="||rhs) & FillCircle(W,C,C+R/2,R/8) end </lang>
graphics.icn provides graphical procedures
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>
Liberty BASIC
![](http://static.miraheze.org/rosettacodewiki/thumb/d/d9/YinYangLB.gif/200px-YinYangLB.gif)
<lang lb> WindowWidth =410
WindowHeight =440
open "Yin & Yang" for graphics_nf_nsb as #w
#w "trapclose [quit]"
call YinYang 200, 200, 200 call YinYang 120, 50, 50
wait
sub YinYang x, y, size
#w "up ; goto "; x; " "; y #w "backcolor black ; color black" #w "down ; circlefilled "; size /2
#w "color 255 255 255 ; backcolor 255 255 255" #w "up ; goto "; x -size /2; " "; y -size /2 #w "down ; boxfilled "; x; " "; y +size /2
#w "up ; goto "; x; " "; y -size /4 #w "down ; backcolor black ; color black ; circlefilled "; size /4 #w "up ; goto "; x; " "; y -size /4 #w "down ; backcolor white ; color white ; circlefilled "; size /12
#w "up ; goto "; x; " "; y +size /4 #w "down ; backcolor white ; color white ; circlefilled "; size /4 #w "up ; goto "; x; " "; y +size /4 #w "down ; backcolor black ; color black ; circlefilled "; size /12
#w "up ; goto "; x; " "; y #w "down ; color black ; circle "; size /2
#w "flush"
end sub
scan
wait
[quit] close #w end
</lang>
Logo
![](http://static.miraheze.org/rosettacodewiki/thumb/1/10/YinYangLogo.png/200px-YinYangLogo.png)
<lang logo>to taijitu :r
; Draw a classic Taoist taijitu of the given radius centered on the current ; turtle position. The "eyes" are placed along the turtle's heading, the ; filled one in front, the open one behind. ; don't bother doing anything if the pen is not down if not pendown? [stop] ; useful derivative values localmake "r2 (ashift :r -1) localmake "r4 (ashift :r2 -1) localmake "r8 (ashift :r4 -1) ; remember where we started localmake "start pos ; draw outer circle pendown arc 360 :r ; draw upper half of S penup forward :r2 pendown arc 180 :r2 ; and filled inner eye arc 360 :r8 fill ; draw lower half of S penup back :r pendown arc -180 :r2 ; other inner eye arc 360 :r8 ; fill this half of the symbol penup forward :r4 fill ; put the turtle back where it started setpos :start pendown
end
- demo code to produce image at right
clearscreen pendown hideturtle taijitu 100 penup forward 150 left 90 forward 150 pendown taijitu 75 </lang>
Mathematica
![](http://static.miraheze.org/rosettacodewiki/thumb/2/27/Mathca.png/200px-Mathca.png)
Mathematica's ability to symbolically build up graphics is often underrated. The following function will create a yin-yang symbol with the parameter size indicating the diameter in multiples of 40 pixels. <lang Mathematica> YinYang[size_] :=
Graphics[{{Circle[{0, 0}, 2]}, {Disk[{0, 0}, 2, {90 Degree, -90 Degree}]}, {White, Disk[{0, 1}, 1]}, {Black, Disk[{0, -1}, 1]}, {Black, Disk[{0, 1}, 1/4]}, {White, Disk[{0, -1}, 1/4]}}, ImageSize -> 40 size]
</lang>
Metapost
![](http://static.miraheze.org/rosettacodewiki/thumb/4/4d/Mp-Yingyang.jpg/200px-Mp-Yingyang.jpg)
The "function" yinyang returns a picture (a primitive type) that can be drawn (and transformed of course in any way) <lang metapost>vardef yinyang(expr u) =
picture pic_; path p_; p_ := halfcircle scaled 2u rotated -90 -- halfcircle scaled u rotated 90 shifted (0, 1/2u) reflectedabout ((0,1), (0,-1)) -- halfcircle scaled u rotated -270 shifted (0, -1/2u) -- cycle; pic_ := nullpicture; addto pic_ contour fullcircle scaled 2u withcolor black; addto pic_ contour p_ withcolor white; addto pic_ doublepath p_ withcolor black withpen pencircle scaled 0.5mm; addto pic_ contour fullcircle scaled 1/3u shifted (0, 1/2u) withcolor white; addto pic_ contour fullcircle scaled 1/3u shifted (0, -1/2u) withcolor black; pic_
enddef;
beginfig(1)
% let's create a Yin Yang symbol with a radius of 5cm draw yinyang(5cm) shifted (5cm, 5cm); % and another one, radius 2.5cm, rotated 180 degrees and translated draw yinyang(2.5cm) rotated 180 shifted (11cm, 11cm);
endfig;
end.</lang>
NetRexx
Writes an SVG document to standard output:
<lang NetRexx>/* NetRexx */
options replace format comments java crossref savelog symbols binary
say "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" say "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'" say " 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>" say "<svg xmlns='http://www.w3.org/2000/svg' version='1.1'" say " xmlns:xlink='http://www.w3.org/1999/xlink'" say " width='30' height='30'>" say " <defs><g id='y'>" say " <circle cx='0' cy='0' r='200' stroke='black'" say " fill='white' stroke-width='1'/>" say " <path d='M0 -200 A 200 200 0 0 0 0 200" say " 100 100 0 0 0 0 0 100 100 0 0 1 0 -200" say " z' fill='black'/>" say " <circle cx='0' cy='100' r='33' fill='white'/>" say " <circle cx='0' cy='-100' r='33' fill='black'/>" say " </g></defs>"
say draw_yinyang(20, 0.05) say draw_yinyang(8, 0.02)
say "</svg>"
return
method draw_yinyang(trans = int, scale = double) inheritable static returns String
yy = String.format(" <use xlink:href='#y' transform='translate(%d,%d) scale(%g)'/>", - [Object Integer(trans), Integer(trans), Double(scale)]) return yy
</lang>
OCaml
<lang ocaml>open Graphics
let draw_yinyang x y radius black white =
let hr = radius / 2 in let sr = radius / 6 in set_color black; set_line_width 6; draw_circle x y radius; set_line_width 0; set_color black; fill_arc x y radius radius 270 450; set_color white; fill_arc x y radius radius 90 270; fill_arc x (y + hr) hr hr 270 450; set_color black; fill_arc x (y - hr) hr hr 90 270; fill_circle x (y + hr) sr; set_color white; fill_circle x (y - hr) sr
let () =
open_graph ""; let width = size_x() and height = size_y() in set_color (rgb 200 200 200); fill_rect 0 0 width height; let w = width / 3 and h = height / 3 in let r = (min w h) / 3 in draw_yinyang w (h*2) (r*2) black white; draw_yinyang (w*2) h r blue magenta; ignore(read_key())</lang>
run with:
$ ocaml graphics.cma yinyang.ml
Perl
<lang perl>sub circle {
my ($radius, $cx, $cy, $fill, $stroke) = @_; print "<circle cx='$cx' cy='$cy' r='$radius' ", "fill='$fill' stroke='$stroke' stroke-width='1'/>\n";
}
sub yin_yang {
my ($rad, $cx, $cy, %opt) = @_; my ($c, $w) = (1, 0); $opt{fill} //= 'white'; $opt{stroke} //= 'black'; $opt{recurangle} //= 0;
print "<g transform='rotate($opt{angle}, $cx, $cy)'>" if $opt{angle};
if ($opt{flip}) { ($c, $w) = ($w, $c) };
circle($rad, $cx, $cy, $opt{fill}, $opt{stroke});
print "<path d='M $cx ", $cy + $rad, "A ", $rad/2, " ", $rad/2, " 0 0 $c $cx $cy ", $rad/2, " ", $rad/2, " 0 0 $w $cx ", $cy - $rad, " ", $rad, " ", $rad, " 0 0 $c $cx ", $cy + $rad, " ", "z' fill='$opt{stroke}' stroke='none' />";
if ($opt{recur} and $rad > 1) { # recursive "eyes" are slightly larger yin_yang($rad/4, $cx, $cy + $rad/2, %opt, angle => $opt{recurangle}, fill => $opt{stroke}, stroke => $opt{fill} ); yin_yang($rad/4, $cx, $cy - $rad/2, %opt, angle => 180 + $opt{recurangle}); } else { circle($rad/5, $cx, $cy + $rad/2, $opt{fill}, $opt{stroke}); circle($rad/5, $cx, $cy - $rad/2, $opt{stroke}, $opt{fill}); } print "</g>" if $opt{angle};
}
print <<'HEAD'; <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
HEAD
yin_yang(200, 250, 250, recur=>1,
angle=>0, recurangle=>90, fill=>'white', stroke=>'black');
yin_yang(100, 500, 500);
print "</svg>"</lang>
Messy code. Note that the larger yin-yang is drawn recursively.
Perl 6
Translation / Modification of C and Perl examples.
<lang perl6>sub circle ($rad, $cx, $cy, $fill = 'white', $stroke = 'black' ){
say "<circle cx='$cx' cy='$cy' r='$rad' fill='$fill' stroke='$stroke' stroke-width='1'/>";
}
sub yin_yang ($rad, $cx, $cy, :$fill = 'white', :$stroke = 'black', :$angle = 90) {
my ($c, $w) = (1, 0); say "<g transform='rotate($angle, $cx, $cy)'>" if $angle; circle($rad, $cx, $cy, $fill, $stroke); say "<path d='M $cx {$cy + $rad}A {$rad/2} {$rad/2} 0 0 $c $cx $cy ", "{$rad/2} {$rad/2} 0 0 $w $cx {$cy - $rad} $rad $rad 0 0 $c $cx ", "{$cy + $rad} z' fill='$stroke' stroke='none' />"; circle($rad/5, $cx, $cy + $rad/2, $fill, $stroke); circle($rad/5, $cx, $cy - $rad/2, $stroke, $fill); say "</g>" if $angle;
}
say '<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">';
yin_yang(40, 50, 50); yin_yang(20, 120, 120);
say '</svg>';</lang>
Seems like something of a cheat since it relies on a web browser / svg image interpreter to actually view the output image. If that's the case, we may as well cheat harder. ;-)
<lang perl6>sub cheat_harder ($scale) {
"☯";
}
say '
', cheat_harder(700), cheat_harder(350), '
';</lang>
☯☯
PostScript
Output:
![](http://static.miraheze.org/rosettacodewiki/thumb/f/f9/PSyinyang.png/300px-PSyinyang.png)
<lang PostScript>%!PS-Adobe-3.0 %%BoundingBox: 0 0 400 400
/fs 10 def /ed { exch def } def /dist { 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt } def /circ {
/r exch def [r neg 1 r { /y exch def [ r 2 mul neg 1 r 2 mul { /x ed x 2 div y 0 0 dist r .05 add gt {( )}{ x 2 div y 0 r 2 div dist dup r 5 div le { pop (.) } { r 2 div le { (@) }{ x 2 div y 0 r 2 div neg dist dup r 5 div le { pop (@)} { r 2 div le {(.)}{ x 0 le {(.)}{(@)}ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } for] } for]
} def
/dis { moveto gsave
{ grestore 0 fs 1.15 mul neg rmoveto gsave {show} forall } forall grestore
} def
/Courier findfont fs scalefont setfont
11 circ 10 390 dis 6 circ 220 180 dis showpage %%EOF</lang>
POV-Ray
![](http://static.miraheze.org/rosettacodewiki/thumb/e/ef/Yys.png/300px-Yys.png)
<lang POV-Ray> // ====== General Scene setup ======
- version 3.7;
global_settings { assumed_gamma 2.2 }
camera{ location <0,2.7,4> look_at <0,.1,0> right x*1.6
aperture .2 focal_point <1,0,0> blur_samples 200 variance 1/10000 }
light_source{<2,4,8>, 1 spotlight point_at 0 radius 10} sky_sphere {pigment {granite scale <1,.1,1> color_map {[0 rgb 1][1 rgb <0,.4,.6>]}}}
- default {finish {diffuse .9 reflection {.1 metallic} ambient .3}
normal {granite scale .2}}
plane { y, -1 pigment {hexagon color rgb .7 color rgb .75 color rgb .65}
normal {hexagon scale 5}}
// ====== Declare one side of the symbol as a sum and difference of discs ======
- declare yang =
difference {
merge { difference { cylinder {0 <0,.1,0> 1} // flat disk box {-1 <1,1,0>} // cut in half cylinder {<.5,-.1,0> <.5,.2,0> .5} // remove half-cicle on one side } cylinder {<-.5,0,0> <-.5,.1,0> .5} // add on the other side cylinder {<.5,0,0> <.5,.1,0> .15} // also add a little dot } cylinder {<-.5,-.1,0> <-.5,.2,0> .15} // and carve out a hole pigment{color rgb 0.1}
}
// ====== The other side is white and 180-degree turned ======
- declare yin =
object {
yang rotate <0,180,0> pigment{color rgb 1}
}
// ====== Here we put the two together: ======
- macro yinyang( ysize )
union { object {yin} object {yang} scale ysize }
- end
// ====== Here we put one into a scene: ======
object { yinyang(1)
translate -y*1.08 }
// ====== And a bunch more just for fun: ======
- declare scl=1.1;
- while (scl > 0.01)
object { yinyang(scl) rotate <0,180,0> translate <-scl*4,scl*2-1,0> rotate <0,scl*360,0> translate <-.5,0,0>} object { yinyang(scl) translate <-scl*4,scl*2-1,0> rotate <0,scl*360+180,0> translate <.5,0,0>}
#declare scl = scl*0.85;
- end
</lang>
PicoLisp
<lang PicoLisp>(de circle (X Y C R)
(>= (* R R) (+ (* (setq X (/ X 2)) X) (* (dec 'Y C) Y) ) ) )
(de yinYang (R)
(for Y (range (- R) R) (for X (range (- 0 R R) (+ R R)) (prin (cond ((circle X Y (- (/ R 2)) (/ R 6)) "#" ) ((circle X Y (/ R 2) (/ R 6)) "." ) ((circle X Y (- (/ R 2)) (/ R 2)) "." ) ((circle X Y (/ R 2) (/ R 2)) "#" ) ((circle X Y 0 R) (if (lt0 X) "." "#") ) (T " ") ) ) ) (prinl) ) )</lang>
Test:
: (yinYang 18) ... .....................## .............................###### .................................###### .......................................######## ...........................................######## ..........................###................########## ........................###########............############ ........................###########............############ ........................###############............############ ............................###########............################ ............................###########............################ ................................###................################ .....................................................################## ...................................................#################### .................................................###################### ...............................................######################## .............................................########################## ......................................################################### ..........................############################################# ........................############################################### ......................################################################# ....................################################################### ..................##################################################### ................################...################################ ................############...........############################ ................############...........############################ ............############...............######################## ............############...........######################## ............############...........######################## ..........################...########################## ........########################################### ........####################################### ......################################# ......############################# ..##################### ###
Prolog
Works with SWI-Prolog and XPCE.
<lang Prolog>ying_yang(N) :- R is N * 100, sformat(Title, 'Yin Yang ~w', [N]), new(W, window(Title)), new(Wh, colour(@default, 255*255, 255*255, 255*255)), new(Bl, colour(@default, 0, 0, 0)), CX is R + 50, CY is R + 50, R1 is R / 2, R2 is R / 8, CY1 is R1 + 50, CY2 is 3 * R1 + 50,
new(E, semi_disk(point(CX, CY), R, w, Bl)), new(F, semi_disk(point(CX, CY), R, e, Wh)), new(D1, disk(point(CX, CY1), R, Bl)), new(D2, disk(point(CX, CY2), R, Wh)), new(D3, disk(point(CX, CY1), R2, Wh)), new(D4, disk(point(CX, CY2), R2, Bl)),
send_list(W, display, [E, F, D1, D2, D3, D4]),
WD is 2 * R + 100, send(W, size, size(WD, WD )), send(W, open).
- - pce_begin_class(semi_disk, path, "Semi disk with color ").
initialise(P, C, R, O, Col) :->
send(P, send_super, initialise),
get(C, x, CX), get(C, y, CY), choose(O, Deb, End), forall(between(Deb, End, I), ( X is R * cos(I * pi/180) + CX, Y is R * sin(I * pi/180) + CY, send(P, append, point(X,Y)))), send(P, closed, @on), send(P, fill_pattern, Col).
- - pce_end_class.
choose(s, 0, 180). choose(n, 180, 360). choose(w, 90, 270). choose(e, -90, 90).
- - pce_begin_class(disk, ellipse, "disk with color ").
initialise(P, C, R, Col) :->
send(P, send_super, initialise, R, R),
send(P, center, C), send(P, pen, 0), send(P, fill_pattern, Col).
- - pce_end_class.
</lang> Example of output :
?- ying_yang(1). true. ?- ying_yang(2). true.
![](http://static.miraheze.org/rosettacodewiki/thumb/6/67/Prolog-yin-yang.png/600px-Prolog-yin-yang.png)
PureBasic
<lang PureBasic>Procedure Yin_And_Yang(x, y, radius)
DrawingMode(#PB_2DDrawing_Outlined) Circle(x, y, 2 * radius, #Black) ;outer circle DrawingMode(#PB_2DDrawing_Default) LineXY(x, y - 2 * radius, x, y + 2 * radius, #Black) FillArea(x + 1, y, #Black, #Black) Circle(x, y - radius, radius - 1, #White) Circle(x, y + radius, radius - 1, #Black) Circle(x, y - radius, radius / 3, #Black) ;small contrasting inner circles Circle(x, y + radius, radius / 3, #White)
EndProcedure
If CreateImage(0, 700, 700) And StartDrawing(ImageOutput(0))
FillArea(1, 1, -1, #White) Yin_And_Yang(105, 105, 50) Yin_And_Yang(400, 400, 148) StopDrawing() ; UsePNGImageEncoder() path$ = SaveFileRequester("Save image", "Yin And yang.png", "*.png", 0) If path$ <> "": SaveImage(0, path$, #PB_ImagePlugin_PNG, 0, 2): EndIf
EndIf</lang>
Python
Text
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)) · ······* ····*··** ····***··** ·····*··*** ········*** ·······****** ···******** ···**·***** ··**···**** ··**·**** ·****** * >>>
Turtle Graphics
This was inspired by the Logo example but diverged as some of the Python turtle graphics primitives such as filling and the drawing of arcs work differently.
<lang python>from turtle import *
mode('logo')
def taijitu(r):
\ Draw a classic Taoist taijitu of the given radius centered on the current turtle position. The "eyes" are placed along the turtle's heading, the filled one in front, the open one behind.
# useful derivative values r2, r4, r8 = (r >> s for s in (1, 2, 3))
# remember where we started x0, y0 = start = pos() startcolour = color() startheading = heading() color('black', 'black')
# draw outer circle pendown() circle(r)
# draw two 'fishes' begin_fill(); circle(r, 180); circle(r2, 180); circle(-r2, 180); end_fill()
# black 'eye' setheading(0); penup(); goto(-(r4 + r8) + x0, y0); pendown() begin_fill(); circle(r8); end_fill()
# white 'eye' color('white', 'white'); setheading(0); penup(); goto(-(r+r4+r8) + x0, y0); pendown() begin_fill(); circle(r8); end_fill()
# put the turtle back where it started penup() setpos(start) setheading(startheading) color(*startcolour)
if __name__ == '__main__':
# demo code to produce image at right reset() #hideturtle() penup() goto(300, 200) taijitu(200) penup() goto(-150, -150) taijitu(100) hideturtle()</lang>
Seed7
![](http://static.miraheze.org/rosettacodewiki/thumb/3/3f/Yinandyang.png/300px-Yinandyang.png)
<lang seed7>$ include "seed7_05.s7i";
include "float.s7i"; include "math.s7i"; include "draw.s7i"; include "keybd.s7i";
const proc: yinYang (in integer: xPos, in integer: yPos, in integer: size) is func
begin pieslice(xPos, yPos, size, 3.0 * PI / 2.0, PI, black); pieslice(xPos, yPos, size, PI / 2.0, PI, white); fcircle(xPos, yPos - size div 2, size div 2, white); fcircle(xPos, yPos + size div 2, size div 2, black); fcircle(xPos, yPos - size div 2, size div 6, black); fcircle(xPos, yPos + size div 2, size div 6, white); circle(xPos, yPos, size, black); end func;
const proc: main is func
begin screen(640, 480); clear(white); KEYBOARD := GRAPH_KEYBOARD; yinYang(100, 100, 80); yinYang(400, 250, 200); readln(KEYBOARD); end func;</lang>
SVG
SVG has no proper functions or variables, but we can translate and rescale a shape after defining it.
<lang xml><?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600">
<symbol id="yinyang">
<g transform="translate(-0.5, -0.5)"> <circle cx="0.5" cy="0.5" r="0.5" fill="white"/> <path d="M 0.5,0 A 0.5,0.5 0 0,1 0.5,1 z" fill="black"/> <circle cx="0.5" cy="0.25" r="0.25" fill="white"/> <circle cx="0.5" cy="0.75" r="0.25" fill="black"/> <circle cx="0.5" cy="0.25" r="0.1" fill="black"/> <circle cx="0.5" cy="0.75" r="0.1" fill="white"/> <circle cx="0.5" cy="0.5" r="0.5" fill="none" stroke="gray" stroke-width=".01"/> </g>
</symbol>
<use xlink:href="#yinyang"
transform="translate(125, 125) scale(200, 200)"/>
<use xlink:href="#yinyang"
transform="translate(375, 375) scale(400, 400)"/>
</svg></lang>
Tcl
![](http://static.miraheze.org/rosettacodewiki/thumb/1/1b/Yinyang-tcl.gif/300px-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>
Visual Basic .NET
This version is based behind a Windows Form Application project in Visual Studio, single form with base values.
<lang vbnet>
Public Class Form1
Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint Dim g As Graphics = e.Graphics g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
DrawTaijitu(g, New Point(50, 50), 200, True) DrawTaijitu(g, New Point(10, 10), 60, True) End Sub
Private Sub DrawTaijitu(ByVal g As Graphics, ByVal pt As Point, ByVal width As Integer, ByVal hasOutline As Boolean) g.FillPie(Brushes.Black, pt.X, pt.Y, width, width, 90, 180) g.FillPie(Brushes.White, pt.X, pt.Y, width, width, 270, 180) g.FillEllipse(Brushes.Black, CSng(pt.X + (width * 0.25)), CSng(pt.Y), CSng(width * 0.5), CSng(width * 0.5)) g.FillEllipse(Brushes.White, CSng(pt.X + (width * 0.25)), CSng(pt.Y + (width * 0.5)), CSng(width * 0.5), CSng(width * 0.5)) g.FillEllipse(Brushes.White, CSng(pt.X + (width * 0.4375)), CSng(pt.Y + (width * 0.1875)), CSng(width * 0.125), CSng(width * 0.125)) g.FillEllipse(Brushes.Black, CSng(pt.X + (width * 0.4375)), CSng(pt.Y + (width * 0.6875)), CSng(width * 0.125), CSng(width * 0.125)) If hasOutline Then g.DrawEllipse(Pens.Black, pt.X, pt.Y, width, width) End Sub
End Class </lang>
- Programming Tasks
- Solutions by Programming Task
- Asymptote
- ALGOL 68
- BBC BASIC
- C
- D
- Delphi
- Examples needing attention
- DWScript
- Go
- Haskell
- Icon
- Unicon
- Icon Programming Library
- J
- Liberty BASIC
- Logo
- Mathematica
- Metapost
- NetRexx
- OCaml
- Perl
- Perl 6
- PostScript
- POV-Ray
- PicoLisp
- Prolog
- PureBasic
- Python
- Seed7
- SVG
- Tcl
- Tk
- Visual Basic .NET
- GUISS/Omit