{東京パラリンピック2020のエンブレムを拡張した図形を表示します。} const title: []char :: "Paralympic 2020" var num: int const centerX: float :: 240.0 const centerY: float :: 240.0 const wndSizeX: int :: (@centerX * 2.0) $ int const wndSizeY: int :: (@centerY * 2.0) $ int var rotX: float var rotY: float var r: []float var rects: []@Rect var wndMain: wnd@Wnd var drawMain: wnd@Draw func main() do @wndMain :: wnd@makeWnd(null, %aspect, @wndSizeX, @wndSizeY, @title) do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, @wndSizeX, @wndSizeY, %scale, %scale, false) do @num :: 34 {12の時に通常のパラリンピックのエンブレムになります。} do @init() do @drawMain.onPaint :: @onPaint do wnd@setOnKeyPress(@onKeyPress) while(wnd@act()) end while end func func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool switch(key) case %up, %right do @num :+ 2 do @init() do @drawMain.paint() ret true case %down, %left if(@num > 4) do @num :- 2 do @init() do @drawMain.paint() end if ret true end switch ret false end func func onPaint(wnd: wnd@WndBase, width: int, height: int) do draw@clearColor(0xFFFFFFFF) for j(0, @num / 2 - 2) for i(0, @num - 1) var index: int :: i * 2 + j % 2 var rot: float :: 2.0 * lib@pi * index $ float / (@num * 2) $ float var cx: float :: @r[j] * lib@cos(rot) + @centerX var cy: float :: @r[j] * lib@sin(rot) + @centerY var inv : bool :: false if(j + 1 < index & index < @num - j) {下側の回転すべき場所} do inv :: true elif(@num + j < index & index < 2 * @num - j) {上側の消えるべき場所} skip i end if do @rects[j].draw(cx, cy, rot, inv) end for end for do draw@render(0) end func func init() var scale: float :: 350.0 / @num $ float var points: []@Point :: #[@num]@Point for i(0, @num - 1) var x: float :: scale * lib@cos(2.0 * lib@pi * i $ float / @num $ float) var y: float :: scale * lib@sin(2.0 * lib@pi * i $ float / @num $ float) do points[i] :: (#@Point).init(x, y) end for var l: []float :: #[@num / 2]float for i(0, @num / 2 - 1) do l[i] :: points[0].getDistance(points[1 + i]) end for do @rects :: #[@num / 2 - 1]@Rect for i(0, @num / 2 - 2) {θ=0の位置でのw, h} var w: float :: l[@num / 2 - 2 - i] var h: float :: l[i] do @rects[i] :: (#@Rect).init(w, h) end for {@r[i]は(i+1)周目の長方形の中心までの距離} do @r :: #[@num / 2 - 1]float do @r[0] :: l[@num / 2 - 2] for i(1, @num / 2 - 2) do @r[i] :: ((@r[i - 1] + @rects[i - 1].w / 2.0) ^ 2.0 + (@rects[i - 1].h / 2.0) ^ 2.0 - (@rects[i].h / 2.0) ^ 2.0) ^ 0.5 + @rects[i].w / 2.0 end for {rr[i]は(i+1)周目の長方形の内側の頂点までの距離} var rr: []float do rr :: #[@num / 2]float do rr[0] :: l[@num / 2 - 1] / 2.0 for i(1, @num / 2 - 1) do rr[i] :: (((rr[i - 1] ^ 2.0 - (@rects[i - 1].h / 2.0) ^ 2.0) ^ 0.5 + @rects[i - 1].w) ^ 2.0 + (@rects[i - 1].h / 2.0) ^ 2.0) ^ 0.5 end for do @rotX :: @centerX do @rotY :: @centerY + ((rr[@num / 2 - 1] ^ 2.0 - (@r[0] / 2.0) ^ 2.0) ^ 0.5 + @rects[0].h / 2.0) / 2.0 end func class Rect() +var w: float +var h: float +func init(w: float, h: float): @Rect do me.w :: w do me.h :: h ret me end func +func draw(cx: float, cy: float, rot: float, inv: bool) if(inv) do cx :: 2.0 * @rotX - cx do cy :: 2.0 * @rotY - cy end if do drawRotRect(cx, cy, me.w, me.h, rot, 0xFF6188FF) func drawRotRect(cx: float, cy: float, w: float, h: float, rot: float, color: int) do w :/ 2.0 do h :/ 2.0 var s: float :: lib@sin(rot) var c: float :: lib@cos(rot) var x1: float :: w * c - h * s + cx var y1: float :: w * s + h * c + cy var x2: float :: -w * c - h * s + cx var y2: float :: -w * s + h * c + cy var x3: float :: -w * c + h * s + cx var y3: float :: -w * s - h * c + cy var x4: float :: w * c + h * s + cx var y4: float :: w * s - h * c + cy do draw@tri(x1, y1, x2, y2, x3, y3, color) do draw@tri(x3, y3, x4, y4, x1, y1, color) end func end func end class class Point() +var x: float +var y: float +func init(x: float, y: float): @Point do me.x :: x do me.y :: y ret me end func +func getDistance(t: @Point): float ret ((me.x - t.x) ^ 2.0 + (me.y - t.y) ^ 2.0) ^ 0.5 end func end class