g | x | w | all
Bytes Lang Time Link
597Chipmunk Basic240606T161949Zroblogic
031Wolfram Language Mathematica210421T085151ZZaMoC
471PostScript190425T164254ZThomas F
483Python 2161013T093203ZKarl Nap
549Python 3 turtle141020T103426ZSp3000
762HTML + CSS141020T124402ZOptimize
nan141023T163354Zuser137
450Mathematica141023T000118ZDavidC
nanPython + Pycairo141020T114414ZEll
324PHP/HTML/SVG141022T100416Zr3mainer
330BBC Basic141020T223459ZLevel Ri
388HTML + ES6141020T125824Zgrc

Chipmunk Basic, 612 603 597 bytes

Latest beta of Chipmunk Basic (v368b2.02) on MacOS. The code is saved to a file korea.bas, then loaded and run from the application menus.

The for loop on line 2 draws a sequence of red and blue circles, calling subroutine p().
On line 3, we call subroutine s() a few times to draw the black rectangles -- comprised of sequences of line segments.
On the following 2 lines, we use a thicker pen (6 pixels) and erase selected parts of the rectangles.

The hard-coded magic numbers scattered around, were calculated via trig and scribbling all over an old envelope, to fit on the 450 by 300 canvas. Note also that Chipmunk Basic uses its own RGB range, from 0 to 100.

Update: Here is an ungolfed and commented version of the code, that produces the 'prototype' image.

option degrees:graphics 0:graphics pensetup 2,2
for i=56to 236:k(78,5,19):p(i):k(0,20,47):p(i+180):next
k(0,0,0):s(236.5,1):s(56.5,1):s(123.5,-1):s(303.5,-1)
graphics pensetup 6,6:k(100,100,100):m(317,210):l(365,242)
m(316,89):l(329,81):m(364,57):l(349,66):m(120,220):l(104,230)
sub p(a):m(225+sin(a)*37,150+cos(a)*37):graphics circle 73:return
sub s(c,f):for i=112to 152step 20:for j=i to i+11:x=225+sin(c)*j
y=150+cos(c)*j:m(x-20.8,y+31.2*f):l(x+20.8,y-31.2*f):next:next:return
sub m(n,o):graphics moveto n,o:return
sub l(n,o):graphics lineto n,o:return
sub k(r,g,b):graphics color r,g,b:return


Wolfram Language (Mathematica), 31 bytes

"SouthKorea"~CountryData~"Flag"

enter image description here

PostScript, 572 477 471 bytes

Golfed code:

5 5 scale 36 24 translate<</R{.75 .05 .19 setrgbcolor}/B{0 .20 .47 setrgbcolor}/a 2 3 atan/b{0 setgray[18 -6 2 12 21 -6 2 12 24 -6 2 12]rectfill 1 setgray{[18 -.5 2 1 24 -.5 2 1]rectfill}if{21 -.5 2 1 rectfill}if}>>begin a neg rotate R 0 0 12 0 180 arc closepath fill B 0 0 12 180 0 arc closepath fill R -6 0 6 0 360 arc closepath fill B 6 0 6 0 360 arc closepath fill true true b 2 a mul rotate false true b 180 rotate true false b -2 a mul rotate false false b showpage

Ungolfed code:

5 5 scale                                     % over-all scale
36 24 translate                               % over-all shift

% define some short-named procedures for later use
<<
  /R {.75 .05 .19 setrgbcolor}                % prodecure for setting red color
  /B {0 .20 .47 setrgbcolor}                  % procedure for setting blue color
  /a 2 3 atan                                 % calculate angle = arctan(2/3) = 33.7°
  /b {                                        % procedure for drawing bars
    0 setgray                                    %   black
    [18 -6 2 12 21 -6 2 12 24 -6 2 12] rectfill  %   draw 3 bars
    1 setgray                                    %   white
    {[18 -.5 2 1 24 -.5 2 1] rectfill} if        %   conditionally draw gap in inner/outer bars 
    {21 -.5 2 1 rectfill} if                     %   conditionally draw gap in middle bar 
  }
>> begin

a neg rotate                                  % rotate -33.7°
R 0 0 12 0 180 arc closepath fill             % big red half circle
B 0 0 12 180 0 arc closepath fill             % big blue half circle
R -6 0 6 0 360 arc closepath fill             % small red circle
B  6 0 6 0 360 arc closepath fill             % small blue circle
true true b                                   % draw bars (with gap in all bars)
2 a mul rotate                                % rotate 67.4°
false true b                                  % draw bars (with gap in inner/outer bars)
180 rotate                                    % rotate 180°
true false b                                  % draw bars (with gap in middle bar)
-2 a mul rotate                               % rotate -67.4°
false false b                                 % draw bars (without gaps)
showpage

Result (as animation to see how it is drawn):

result

Python 2, 483 bytes

from math import*
w,k,r,b="255 "*3,"0 "*3,"198 12 48 ","0 52 120 "
print "P3 600 400 255 "
a=atan2(2,3)
c,s=cos(a),sin(a)
T=lambda x,y:(c*x-s*y,s*x+c*y)
S=lambda x,y:150<x<216.6and x%25<16.6and y*y<2500
C=lambda x,y,p=50:(x-p)**2+y*y<2500
for y in range(-200,200):
 for x in range(-300,300):X,Y=T(x,y);W,Z=T(-x,y);print [[w,k][(S(abs(X),Y)and(Y*Y>16or(166.6<X<191.4or-200>X or 0>X>-166.6)))or(S(abs(W),Z)and(W>0 or abs(Z)>4))],[b,r][(Z<0 or C(W,Z))and not C(W,Z,-50)]][W*W+Z*Z<10000]

Possible improvements:

Output as text PPM, usage:

python golf_korea.py > korea.ppm

enter image description here

ungolfed beta version

from math import*
w,k,r,b="255 255 255 ", "0 0 0 ", "255 0 0 ", "0 0 255 "
g="0 255 0 "
print "P3 600 400 255 "
a=atan2(2,3)
c,s=cos(a),sin(a)
trans=lambda x,y:(c*x-s*y,s*x+c*y)
stripe=lambda x:150<x<216.6 and x%25<16.6
small=lambda x,y,p=50:(x-p)**2+y*y<2500
for y in range(-200,200):
 for x in range(-300,300):
  X,Y=trans(x,y)
  W,Z=trans(-x,y)
  if stripe(abs(X)) and Y*Y<2500:
   if abs(Y)>4:  
    print k
   else:
    if X>0:
     if 166.6<X<191.4:
      print k
     else:
      print w
    else:
     if -200<X<-166.6:
      print w
     else:
      print k
  elif stripe(abs(W)) and Z*Z<2500 and(W>0 or abs(Z)>4):
   print k
  elif W*W+Z*Z<100*100:
   if (Z<0 or small(W,Z)) and not small(W,Z,-50):
    print r
   else:
    print b
  else:
   print w

Python 3 turtle (552 549 bytes)

Flag

(Full size image)

Edit: Now that we have Stack Snippets, here's a Stack Snippet test using Skulpt, with the help of ArtOfCode's answer here. Unfortunately, Skulpt hasn't fully implemented Python yet, so I had to mutilate half my code to get this to work. In other words, this snippet is only meant to indicate how my program works (without needing to pull up Python).

(Also, I'm finding that this might not actually work on some browsers...)

function out(a){var b=document.getElementById("output");b.innerHTML+=a}function builtinRead(a){if(void 0===Sk.builtinFiles||void 0===Sk.builtinFiles.files[a])throw"File not found: '"+a+"'";return Sk.builtinFiles.files[a]}
$(document).ready(function run(){Sk.canvas="canvas";Sk.configure({output:out,read:builtinRead});try{Sk.importMainWithBody("<stdin>",!1,'import turtle\nimport math\nt=turtle.Turtle()\nt.speed(9)\nR="#c60c30"\nr=56.3\nk=0.6\ns=60*k\noffsetx,offsety=-215,-145\nt.up()\nt.goto(offsetx,offsety)\nt.down()\ndef q():t.rt(90)\ndef Q():t.lt(90)\ndef K():t.color("black");t.begin_fill();q()\ndef A(g,G):t.fd(g);Q();t.fd(G);Q();t.fd(g);Q();t.fd(G);Q()\ndef E():t.up();t.fd(s);t.down();Q();t.end_fill();t.up();t.fd(30*k);t.down();\ndef i():K();t.up();t.bk(s);t.down();A(120*k,20*k);E()\ndef I():K();t.up();t.fd(5*k);t.down();A(55*k,20*k);t.up();t.bk(65*k);t.down();A(55*k,20*k);E()\ndef C():t.circle(120*k,180)\nA(720*k,480*k)\nt.seth(r)\nt.up()\nt.goto(459.8*k+offsetx,173.4*k+offsety)\nt.down()\nt.color(R)\nt.begin_fill()\nC()\nt.end_fill()\nt.begin_fill()\nt.color("#003478")\nC()\nt.circle(s)\nt.end_fill()\nt.color(R)\nC()\nt.begin_fill()\nt.circle(s)\nt.end_fill()\nq()\nt.up()\nt.fd(s)\nt.down()\ni()\ni()\ni()\nt.up()\nt.bk(530*k)\nt.down()\nI()\nI()\nI()\nt.up()\nt.fd(170*k)\nt.rt(2*r)\nt.fd(180*k)\nt.down()\nI()\ni()\nI()\nt.up()\nt.bk(530*k)\nt.down()\ni()\nI()\ni()\n')}catch(a){throw Error(a.toString());}})
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script><script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script><script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>
<canvas height="320" width="480" id="canvas" style="border:1px solid gray">Your browser does not support HTML5 Canvas!</canvas>


Actual code:

import turtle as t
b=t.begin_fill
c=t.circle
e=t.end_fill
f=t.fillcolor
R="#c60c30"
r=56.3
F=t.fd
B=t.bk
s=60
def q():t.rt(90)
def Q():t.lt(90)
def K():f(0,0,0);b();q()
def A(g,G):exec("F(g);Q();F(G);Q();"*2)
def E():F(s);Q();e();F(30)
def i():K();B(s);A(120,20);E()
def I():K();F(5);A(55,20);B(65);A(55,20);E()
def C():c(120,180)
A(720,480)
t.seth(r)
t.up()
t.goto(459.8,173.4)
f(R)
b()
C()
e()
b()
f("#003478")
C()
c(s)
e()
C()
f(R)
b()
c(s)
e()
q()
F(s)
i()
i()
i()
B(530)
I()
I()
I()
F(170)
t.rt(2*r)
F(180)
I()
i()
I()
B(530)
i()
I()
i()
t.ht()

Since the turtle's such a slowpoke, if you want instant results you can add t.tracer(0) after the first line before you run the script.

Note: For some reason turtle keeps drawing what looks like extra black pixels even though I've already called up(), and I have no idea why...

HTML + CSS, 966 906 843 792 762 bytes

Not a winner anytime, but lots of fun drawing in CSS. This can be golfed a lot though.

CSS, HTML:

*{position:fixed}a{background:linear-gradient(0deg,#003478 50%,#C60C30 50%);width:2in;height:2in;transform:rotate(.6rad);top:1in;left:2in}d,e{width:50%;height:50%;background:#C60C30;left:0;top:25%}a,d,e{border-radius:50%}d{background:#003478;left:50%}b,i{width:1in;height:26em;top:-1em;left:15em;transform:rotate(.98rad)}g,f,k,j{width:1in;height:17%;background:repeating-linear-gradient(0deg,#000,#000 1em,#fff 1em,#fff 1.5em);bottom:0;left:0}g,j,p{top:-.5em}b{transform:rotate(-.98rad)}c,p,v,x{height:2em;width:.5em;background:#fff;transform:rotate(.98rad)}p{top:2.8in;left:28em;transform:rotate(-.98rad) scale(1,4)}x{top:3.9em;left:28.4em}c,v{top:23.8em;transform:none}c{top:3.5em}body{height:4in;width:6in;border:1px solid
<a><d><e></a><b><f><g></b><i><j><k></i><p></p><x><v><c

;border:1px solid is just for show as the <body> tag has clear boundaries which can be observed by Inspector or similar tools, as stated by the OP

NOTE Works only in Firefox (or Chrome canary/dev) due to usage non vendor specific transforms and gradients.

See it in action

C++ TOO LARGE

Attempted this using my home made PPM drawing library. It's technically scalable, but I'm limited by my recursive fill function because it's unreliable and likes to segfault, I think it's using up too much memory, so I won't actually let the user set the scale. The image is irregular because the coordinates I entered for each corner of the bars are slightly off. enter image description here

I set it up to start with a black background, then put a white circle in the middle, then red and blue circles in that. Used recursive fills to add the rest of red and blue. Then drew rectangles with white lines to mark the black bars. Split the black background into 4 sections with white lines and used 4 recursive fills to make each section white. Doing it in 1 pass would have caused a segfault. It's still very slow to render.

Ungolfed main code ( the rest of the library is too large, golfing this doesn't matter )

#include "PPMDraw.h"
#include <iostream>

int main(){
    std::cout << "Drawing Korean Flag" << std::endl;

    int scale = 150;
    int width = 3 * scale;
    int height = 2 * scale;

    int xc = width/2;
    int yc = height/2;

    // coords for the bar corners
    float nwax = -0.773; float nway = -0.813;
    float nwbx = -0.707; float nwby = -0.773;
    float nwcx = -1.000; float nwcy = -0.360;
    float nwdx = -1.050; float nwdy = -0.400;
    float nwex = -0.667; float nwey = -0.747;
    float nwfx = -0.613; float nwfy = -0.693;
    float nwgx = -0.880; float nwgy = -0.293;
    float nwhx = -0.947; float nwhy = -0.333;
    float nwix = -0.560; float nwiy = -0.667;
    float nwjx = -0.507; float nwjy = -0.627;
    float nwkx = -0.773; float nwky = -0.227;
    float nwlx = -0.840; float nwly = -0.267;

    float neax = 0.747; float neay = -0.813;
    float nebx = 0.867; float neby = -0.627;
    float necx = 0.813; float necy = -0.587;
    float nedx = 0.680; float nedy = -0.773;
    float neex = 0.893; float neey = -0.587;
    float nefx = 1.030; float nefy = -0.400;
    float negx = 0.960; float negy = -0.360;
    float nehx = 0.840; float nehy = -0.547;
    float neix = 0.640; float neiy = -0.747;
    float nejx = 0.920; float nejy = -0.333;
    float nekx = 0.853; float neky = -0.293;
    float nelx = 0.587; float nely = -0.693;
    float nemx = 0.533; float nemy = -0.667;
    float nenx = 0.667; float neny = -0.493;
    float neox = 0.600; float neoy = -0.440;
    float nepx = 0.480; float nepy = -0.627;
    float neqx = 0.693; float neqy = -0.440;
    float nerx = 0.813; float nery = -0.267;
    float nesx = 0.747; float nesy = -0.227;
    float netx = 0.627; float nety = -0.400;

    float swax = -0.773; float sway = 0.200;
    float swbx = -0.507; float swby = 0.613;
    float swcx = -0.560; float swcy = 0.653;
    float swdx = -0.840; float swdy = 0.253;
    float swex = -0.880; float swey = 0.280;
    float swfx = -0.760; float swfy = 0.453;
    float swgx = -0.813; float swgy = 0.493;
    float swhx = -0.947; float swhy = 0.320;
    float swix = -0.733; float swiy = 0.507;
    float swjx = -0.613; float swjy = 0.680;
    float swkx = -0.667; float swky = 0.720;
    float swlx = -0.787; float swly = 0.547;
    float swmx = -0.987; float swmy = 0.347;
    float swnx = -0.707; float swny = 0.760;
    float swox = -0.773; float swoy = 0.800;
    float swpx = -1.053; float swpy = 0.387;

    float seax = 0.747; float seay = 0.200;
    float sebx = 0.813; float seby = 0.253;
    float secx = 0.693; float secy = 0.427;
    float sedx = 0.627; float sedy = 0.387;
    float seex = 0.853; float seey = 0.280;
    float sefx = 0.920; float sefy = 0.320;
    float segx = 0.800; float segy = 0.507;
    float sehx = 0.733; float sehy = 0.453;
    float seix = 0.960; float seiy = 0.347;
    float sejx = 1.036; float sejy = 0.387;
    float sekx = 0.893; float seky = 0.573;
    float selx = 0.840; float sely = 0.520;
    float semx = 0.600; float semy = 0.427;
    float senx = 0.667; float seny = 0.467;
    float seox = 0.547; float seoy = 0.653;
    float sepx = 0.480; float sepy = 0.613;
    float seqx = 0.707; float seqy = 0.493;
    float serx = 0.773; float sery = 0.547;
    float sesx = 0.640; float sesy = 0.733;
    float setx = 0.547; float sety = 0.680;
    float seux = 0.813; float seuy = 0.573;
    float sevx = 0.880; float sevy = 0.613;
    float sewx = 0.747; float sewy = 0.800;
    float sexx = 0.693; float sexy = 0.747;

    PPMDraw flag = PPMDraw(width, height);
    flag.fill(0, 0, 0);

    // draw white circle in middle
    flag.set_color(255, 255, 255);
    flag.draw_fill_circle(xc, yc, scale/2);

    // draw red and blue portions of circle
    flag.set_color(255, 0, 0);
    flag.draw_fill_circle(xc - .21*scale, yc - .14*scale, scale/3.9);
    flag.set_color(0, 0, 255);
    flag.draw_fill_circle(xc + .21*scale, yc + .14*scale, scale/3.9);
    flag.set_color(255, 0, 0);
    flag.recursive_fill(xc + .21*scale, yc - .21*scale);
    flag.set_color(0, 0, 255);
    flag.recursive_fill(xc - .21*scale, yc + .21*scale);

    // draw the northwest bars
    flag.set_color(255, 255, 255);

    flag.draw_line(xc + nwax*scale, yc + nway*scale, xc + nwbx*scale, yc + nwby*scale);
    flag.draw_line(xc + nwax*scale, yc + nway*scale, xc + nwdx*scale, yc + nwdy*scale);
    flag.draw_line(xc + nwbx*scale, yc + nwby*scale, xc + nwcx*scale, yc + nwcy*scale);
    flag.draw_line(xc + nwcx*scale, yc + nwcy*scale, xc + nwdx*scale, yc + nwdy*scale);

    flag.draw_line(xc + nwex*scale, yc + nwey*scale, xc + nwfx*scale, yc + nwfy*scale);
    flag.draw_line(xc + nwex*scale, yc + nwey*scale, xc + nwhx*scale, yc + nwhy*scale);
    flag.draw_line(xc + nwfx*scale, yc + nwfy*scale, xc + nwgx*scale, yc + nwgy*scale);
    flag.draw_line(xc + nwhx*scale, yc + nwhy*scale, xc + nwgx*scale, yc + nwgy*scale);

    flag.draw_line(xc + nwix*scale, yc + nwiy*scale, xc + nwjx*scale, yc + nwjy*scale);
    flag.draw_line(xc + nwix*scale, yc + nwiy*scale, xc + nwlx*scale, yc + nwly*scale);
    flag.draw_line(xc + nwjx*scale, yc + nwjy*scale, xc + nwkx*scale, yc + nwky*scale);
    flag.draw_line(xc + nwlx*scale, yc + nwly*scale, xc + nwkx*scale, yc + nwky*scale);
    //NE
    flag.draw_line(xc + neax*scale, yc + neay*scale, xc + nebx*scale, yc + neby*scale);
    flag.draw_line(xc + neax*scale, yc + neay*scale, xc + nedx*scale, yc + nedy*scale);
    flag.draw_line(xc + nebx*scale, yc + neby*scale, xc + necx*scale, yc + necy*scale);
    flag.draw_line(xc + necx*scale, yc + necy*scale, xc + nedx*scale, yc + nedy*scale);

    flag.draw_line(xc + neex*scale, yc + neey*scale, xc + nefx*scale, yc + nefy*scale);
    flag.draw_line(xc + neex*scale, yc + neey*scale, xc + nehx*scale, yc + nehy*scale);
    flag.draw_line(xc + nefx*scale, yc + nefy*scale, xc + negx*scale, yc + negy*scale);
    flag.draw_line(xc + nehx*scale, yc + nehy*scale, xc + negx*scale, yc + negy*scale);

    flag.draw_line(xc + neix*scale, yc + neiy*scale, xc + nejx*scale, yc + nejy*scale);
    flag.draw_line(xc + neix*scale, yc + neiy*scale, xc + nelx*scale, yc + nely*scale);
    flag.draw_line(xc + nejx*scale, yc + nejy*scale, xc + nekx*scale, yc + neky*scale);
    flag.draw_line(xc + nelx*scale, yc + nely*scale, xc + nekx*scale, yc + neky*scale);

    flag.draw_line(xc + nemx*scale, yc + nemy*scale, xc + nenx*scale, yc + neny*scale);
    flag.draw_line(xc + nemx*scale, yc + nemy*scale, xc + nepx*scale, yc + nepy*scale);
    flag.draw_line(xc + nepx*scale, yc + nepy*scale, xc + neox*scale, yc + neoy*scale);
    flag.draw_line(xc + nenx*scale, yc + neny*scale, xc + neox*scale, yc + neoy*scale);

    flag.draw_line(xc + neqx*scale, yc + neqy*scale, xc + nerx*scale, yc + nery*scale);
    flag.draw_line(xc + neqx*scale, yc + neqy*scale, xc + netx*scale, yc + nety*scale);
    flag.draw_line(xc + nerx*scale, yc + nery*scale, xc + nesx*scale, yc + nesy*scale);
    flag.draw_line(xc + netx*scale, yc + nety*scale, xc + nesx*scale, yc + nesy*scale);

    //sw
    flag.draw_line(xc + swax*scale, yc + sway*scale, xc + swbx*scale, yc + swby*scale);
    flag.draw_line(xc + swax*scale, yc + sway*scale, xc + swdx*scale, yc + swdy*scale);
    flag.draw_line(xc + swbx*scale, yc + swby*scale, xc + swcx*scale, yc + swcy*scale);
    flag.draw_line(xc + swcx*scale, yc + swcy*scale, xc + swdx*scale, yc + swdy*scale);

    flag.draw_line(xc + swex*scale, yc + swey*scale, xc + swfx*scale, yc + swfy*scale);
    flag.draw_line(xc + swex*scale, yc + swey*scale, xc + swhx*scale, yc + swhy*scale);
    flag.draw_line(xc + swfx*scale, yc + swfy*scale, xc + swgx*scale, yc + swgy*scale);
    flag.draw_line(xc + swhx*scale, yc + swhy*scale, xc + swgx*scale, yc + swgy*scale);

    flag.draw_line(xc + swix*scale, yc + swiy*scale, xc + swjx*scale, yc + swjy*scale);
    flag.draw_line(xc + swix*scale, yc + swiy*scale, xc + swlx*scale, yc + swly*scale);
    flag.draw_line(xc + swjx*scale, yc + swjy*scale, xc + swkx*scale, yc + swky*scale);
    flag.draw_line(xc + swlx*scale, yc + swly*scale, xc + swkx*scale, yc + swky*scale);

    flag.draw_line(xc + swmx*scale, yc + swmy*scale, xc + swnx*scale, yc + swny*scale);
    flag.draw_line(xc + swmx*scale, yc + swmy*scale, xc + swpx*scale, yc + swpy*scale);
    flag.draw_line(xc + swpx*scale, yc + swpy*scale, xc + swox*scale, yc + swoy*scale);
    flag.draw_line(xc + swnx*scale, yc + swny*scale, xc + swox*scale, yc + swoy*scale);

    //se
    flag.draw_line(xc + seax*scale, yc + seay*scale, xc + sebx*scale, yc + seby*scale);
    flag.draw_line(xc + seax*scale, yc + seay*scale, xc + sedx*scale, yc + sedy*scale);
    flag.draw_line(xc + sebx*scale, yc + seby*scale, xc + secx*scale, yc + secy*scale);
    flag.draw_line(xc + secx*scale, yc + secy*scale, xc + sedx*scale, yc + sedy*scale);

    flag.draw_line(xc + seex*scale, yc + seey*scale, xc + sefx*scale, yc + sefy*scale);
    flag.draw_line(xc + seex*scale, yc + seey*scale, xc + sehx*scale, yc + sehy*scale);
    flag.draw_line(xc + sefx*scale, yc + sefy*scale, xc + segx*scale, yc + segy*scale);
    flag.draw_line(xc + sehx*scale, yc + sehy*scale, xc + segx*scale, yc + segy*scale);

    flag.draw_line(xc + seix*scale, yc + seiy*scale, xc + sejx*scale, yc + sejy*scale);
    flag.draw_line(xc + seix*scale, yc + seiy*scale, xc + selx*scale, yc + sely*scale);
    flag.draw_line(xc + sejx*scale, yc + sejy*scale, xc + sekx*scale, yc + seky*scale);
    flag.draw_line(xc + selx*scale, yc + sely*scale, xc + sekx*scale, yc + seky*scale);

    flag.draw_line(xc + semx*scale, yc + semy*scale, xc + senx*scale, yc + seny*scale);
    flag.draw_line(xc + semx*scale, yc + semy*scale, xc + sepx*scale, yc + sepy*scale);
    flag.draw_line(xc + sepx*scale, yc + sepy*scale, xc + seox*scale, yc + seoy*scale);
    flag.draw_line(xc + senx*scale, yc + seny*scale, xc + seox*scale, yc + seoy*scale);

    flag.draw_line(xc + seqx*scale, yc + seqy*scale, xc + serx*scale, yc + sery*scale);
    flag.draw_line(xc + seqx*scale, yc + seqy*scale, xc + setx*scale, yc + sety*scale);
    flag.draw_line(xc + serx*scale, yc + sery*scale, xc + sesx*scale, yc + sesy*scale);
    flag.draw_line(xc + setx*scale, yc + sety*scale, xc + sesx*scale, yc + sesy*scale);

    flag.draw_line(xc + seux*scale, yc + seuy*scale, xc + sevx*scale, yc + sevy*scale);
    flag.draw_line(xc + seux*scale, yc + seuy*scale, xc + sexx*scale, yc + sexy*scale);
    flag.draw_line(xc + sevx*scale, yc + sevy*scale, xc + sewx*scale, yc + sewy*scale);
    flag.draw_line(xc + sexx*scale, yc + sexy*scale, xc + sewx*scale, yc + sewy*scale);

    // fill in the black to white
    flag.draw_line(xc, yc - scale/2, xc, 0);
    flag.draw_line(xc, yc + scale/2, xc, height);
    flag.draw_line(xc - scale/2, yc, 0, yc);
    flag.draw_line(xc + scale/2, yc, width, yc);

    flag.recursive_fill(0, 0);
    flag.recursive_fill(0, height-1);
    flag.recursive_fill(width - 1, 0);
    flag.recursive_fill(width - 1, height - 1);

    flag.save("flag.ppm");

}

Mathematica 404 450

b=1&~Array~13;a=ReplacePart[b,7-> 0];d=Disk;r=RGBColor;
z@{q_,p_,s_}:=ArrayPlot[{q,q,{},p,p,{},s,s},Frame-> False,ImageSize-> 155];
m=r@@{0,.2,.5};
o=r@@{.8,0,.2};
t=-19.1;u=-12.75;v=-5;q=-3.33;
Graphics[{Line[{{-36,-24},{36,-24},{36,24},{-36,24},{-36,-24}}],
Inset[Rotate[z@#,#2 125 Degree],#3]&@@@{{{b,a,b},1,{t,u}},{{a,b,a},1,{-t,-u}},
{{a,a,a},-1,{-t,u}},{{b,b,b},-1,{t,-u}}},
{o,d[{0,0},12,{-.2 Pi,.8Pi}],m, d[{0,0},12,{.8Pi,1.8Pi}],o,d[{v,-q},6],m,d[{-v,q},6]}}]

flag

Python + Pycairo, 371 370 366 bytes

Flag

from cairo import*
p=3.141593
c=Context(SVGSurface("F",12,8))
C=c.set_source_rgb;R=c.rectangle;T=c.rotate;F=c.fill
C(1,1,1);R(0,0,12,8);F()
c.translate(6,4);T(.588);b=3188
for o in[(0,.2,.47),(.77,.05,.19)]*2:C(*o);i=b/2%2;b+=1;c.arc(i,0,2-i,0,p+i*p);F();T(p)
C(0,0,0)
for x in(p,1.966)*2:
 for y in.5,0,1:
    for z in-1,1:R(3+y,-z,1./3,z*(2.75+b%2)/3);F()
    b/=2
 T(x)

Outputs a tiny SVG file named F.

PHP/HTML/SVG, 324

(line breaks added for legibility)

<?=gzinflate(base64_decode('tVHBioMwFPyVwF5WSOzLi/tswQjdu9cevIk1KqtriaFd9utrgpSWFva0PPImMwzDkGTz
uWXnvrl8Tj8aOPAUebLNs5Y5W33PZrKjtpOrXPOuVEy7KMiD54mKMY3yrO5tPTTMaonM9MOg32qCWgHb5Nmpch076kIih/2y
PC4jRRCIU6BhbkwGV7lmAagk3d5nCfwQdKByVBwOFLagQu6exZLNzk5fjU+B9S4u/dF1Gh/apRw6Cb83uzHm0S69/cWbSIkx
YfSf5QT6dkk5UoACIeAfXTftepb/za8='));

The compressed data expands to the same SVG data as my earlier answer shown below, but with two changes to aid compression:

  1. The two <use> sections are expanded to the original content of the <defs> section. This makes the source text longer, but reduces the entropy so it compresses better.

  2. In the first <g> element, I changed transform=translate(36,24)rotate(33.69) to transform=rotate(33.69)translate(43.27). This has the same effect geometrically, but compresses better because the sequence ><g transform=rotate( now appears twice.

By default, PHP will serve this as Content-Type: text/html, so the invalid XML syntax shouldn't be a problem.

SVG/HTML, 463

The HTML parser isn't too fussed about correct syntax, so we can do away with quotation marks in the parameters as long as they don't contain any spaces. It should be possible to squeeze this down further with a bit of Javascript.

<svg viewBox=0,0,72,48><defs><path d=M-25-6V6Zm3,0V6m3,0V-6M19-6V6Zm3,0V6m3,0V-6Z stroke=#000
stroke-width=2 id=p /></defs><g transform=translate(36,24)rotate(33.69)><circle r=12 fill=#c60c30
/><path d=M12,0A12,12,0,0,1-12,0A6,6,0,0,0,0,0A6,6,0,0,1,12,0Z fill=#003478 /><use xlink:href=#p
/><path d=M17,0h10z stroke=#fff stroke-width=1 /><g transform=rotate(112.62)><use xlink:href=#p
/><path d=M-27,0h4Zm6,0h4ZM20,0h4Z stroke=#fff stroke-width=1 /></g></g></svg>

BBC Basic, 349 343 ASCII characters, tokenised file size 330

Download emulator at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

  p=1049q=25r=100VDU4118;275;-1,49,3076;19,7,-1;-1;531;255;7693;q;40;0;q,97,1200;800;29,640;400;
  FORa=38TO56STEP0.01x=r*COS(a)y=r*SIN(a)b=a*7DIV44/2IFb=3.5z=y<0ELSEz=x>0
  VDU18;1,p;-x;-y;q,153,r;0;18;2,p;x;y;q,153,r;0;18;0
  IFABS(y)DIV1=56VDUp;x*b+y;y*b-x;q;x/3;y/3;q,113,-2*y;2*x;18;7:b-=0.1VDUp;x*b+y/12;y*b-x/12;q;x/2;y/2;q,112-z,-y/6;x/6;
  NEXT

Using the correct colours added a lot, but golfing all the graphics commands down to raw VDU codes gives a saving of 6 characters overall compared with my original post. All graphics on the BBC micro is done via machine-specific ASCII control codes, so instead of using high-level graphics commands you can feed bytes direct to the VDU controller (generally shorter but at great expense to readability). A value ending in semicolon instead of comma is a 16-bit little-endian representation of 2 bytes.

Ungolfed version

  MODE16
  VDU19,1,-1,49,4,12                :REM adjust shade of red 
  VDU19,7,-1,-1,-1,-1               :REM adjust shade of white to full brightness (63 is 2's complement representation of -1
  VDU19,4,-1,0,13,30                :REM adjust shade of blue
  RECTANGLEFILL40,0,1200,800        :REM plot background rectangle
  ORIGIN640,400
  FORa=38TO56STEP0.01
    x=COS(a)*100
    y=SIN(a)*100
    GCOL1:CIRCLEFILL-x,-y,100       :REM red
    GCOL4:CIRCLEFILLx,y,100         :REM blue
    GCOL0                           :REM black
    b=a*7DIV44/2                    :REM divide a by 2*(22/7) to get integer representation, then divide by 2 again.
    IFb=3.5THENz=y<0ELSEz=x>0       :REM decide whether to cut bar
    REM If the angle is correct (100*sin(a) = 56) draw bar. If required, cut out the middle of the bar.
    IFABS(INT(y))=56 MOVEx*b+y,y*b-x:MOVEBY x/3,y/3:PLOT113,-2*y,2*x:GCOL7:b-=0.1:MOVEx*b+y/12,y*b-x/12:MOVEBY x/2,y/2:IFz PLOT113,-y/6,x/6
  NEXT

At the beginning of the program I move the origin to the centre of the screen.

I don't draw any large coloured half circles. Instead I run a loop that draws small red and blue circles, spinning in an anticlockwise direction. I do nearly 3 complete revolutions (starting with blue at the right) which is obviously more than enough to fill in the disc. I stop on the 3rd revolution, just when the blue at lower right is in the correct position to line up with the bars (which have to be plotted.)

When the angle is right, I draw one of the bars. the vector x,y for drawing the current small blue circle serves to tell in which direction the bar should be. For each of the 3 revolutions, a different value of the integer a*7DIV44 is calculated, which tells whether the first, second or third bar should be drawn, with its inner edge 6/8,7/8 or 8/8 units from the centre (according to the units used in the question spec.) Because the program units are 1/4 of those in the spec, this is still a half-unit, so we divide by 2 again before saving to variable ´b´ to avoid repeated halving later.

The bars are drawn solid, then the middle is deleted if necessary. This prevents kinks from joining half-bars. The variable z indicates if a bar should be cut. That is, when y is negative for the middle bars and when x is positive for the other bars.

MOVE is an absolute move. MOVEBY is a relative move. PLOT133 considers the last two graphics cursor positions, plus the new one specified (in relative coordinates) as three corners of a parallelogram, and plots that parallelogram.

Output (& discussion of language limitations)

I selected a screen mode of 1280x800 logical pixels = 640x400 physical pixels, which by default has a black background. Onto this I draw a white rectangle from -600,-400 to 600,400 to act as my "canvas."

BBC Basic can handle 16 colours at once, from a reprogrammable pallete. But it only supports 18-bit colour, whereas the question specifies the colours as 24-bit. The colours as close as possible.

enter image description here

HTML + ES6, 388

<canvas id=D width=576 height=384><script>c=D.getContext('2d')
T=x=>c.translate(x*72,x*48)
R=(x,y)=>T(4)+c.rotate(x*.59)+T(-4)+eval('for(i=j=0;i*j<6;i+=(j^=1))c.fillRect(72+24*i+(i>2)*288,144+j*52,16,44+52*(y>>i&1-j))')
A=(w,x,y,z)=>(c.fillStyle=c.fill()+c.beginPath()||w)*c.arc(x*4,192-y,48*y,0,3.1,z)||A
R(-1,21)
R(2,7)
A(r='#C60C30',72,2,1)('#003478',72,2)(0,84,1,1)(r,60,1)()</script>

If your browser supports ES6, you can view it on JSFiddle or run the snippet.

It constructs the flag out of some basic shapes, rotating the canvas first to account for the angles.