One well-known symbol of the philosophy of duality known as yin and yang is the taijitu.



Task

   Create a function that, given a parameter representing size, generates such a symbol scaled to the requested size.
   Generate and display the symbol for two different (small) sizes.


--
-- demo\rosetta\Yin_and_yang.exw
-- =============================
--
with javascript_semantics
include pGUI.e

Ihandle dlg, canvas
cdCanvas cd_canvas

procedure cdCanvasSecArc(cdCanvas hCdCanvas, atom xc, atom yc, atom w, atom h, atom angle1, atom angle2) 
-- cdCanvasSector does not draw anti-aliased edges, but cdCanvasArc does, so over-draw...
    cdCanvasSector(hCdCanvas, xc, yc, w, h, angle1, angle2) 
    cdCanvasArc   (hCdCanvas, xc, yc, w, h, angle1, angle2) 
end procedure

procedure yinyang(atom  cx, cy, r)
    cdCanvasArc(cd_canvas, cx, cy, r, r, 0, 360) 
    cdCanvasSecArc(cd_canvas, cx, cy, r, r, 270, 90) 
    cdCanvasSecArc(cd_canvas, cx, cy-r/4, r/2-1, r/2-1, 0, 360) 
    cdCanvasSetForeground(cd_canvas, CD_WHITE)
    cdCanvasSecArc(cd_canvas, cx, cy+r/4, r/2-1, r/2-1, 0, 360) 
    cdCanvasSecArc(cd_canvas, cx, cy-r/4, r/8, r/8, 0, 360) 
    cdCanvasSetForeground(cd_canvas, CD_BLACK)
    cdCanvasSecArc(cd_canvas, cx, cy+r/4, r/8, r/8, 0, 360) 
end procedure

function redraw_cb(Ihandle /*ih*/)
    integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE"),
             r = min(width,height)-40,
            cx = floor(width/2),
            cy = floor(height/2)
    cdCanvasActivate(cd_canvas)
    cdCanvasClear(cd_canvas) 
    yinyang(cx-r*.43,cy+r*.43,r/6)
    yinyang(cx,cy,r)
    cdCanvasFlush(cd_canvas)
    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    IupGLMakeCurrent(canvas)
    if platform()=JS then
        cd_canvas = cdCreateCanvas(CD_IUP, canvas)
    else
        atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
        cd_canvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
    end if
    cdCanvasSetBackground(cd_canvas, CD_WHITE)
    cdCanvasSetForeground(cd_canvas, CD_BLACK)
    return IUP_DEFAULT
end function

function canvas_resize_cb(Ihandle /*canvas*/)
    integer {canvas_width, canvas_height} = IupGetIntInt(canvas, "DRAWSIZE")
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    cdCanvasSetAttribute(cd_canvas, "SIZE", "%dx%d %g", {canvas_width, canvas_height, res})
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()
    canvas = IupGLCanvas("RASTERSIZE=340x340")
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "RESIZE_CB", Icallback("canvas_resize_cb"),
                             "ACTION", Icallback("redraw_cb")})
    dlg = IupDialog(canvas, `TITLE="Yin and Yang"`)
    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()
