2019年05月08日

風邪引いてました

 元号が変わった日に急に熱が出て、連休後半はぼろぼろだった。発熱→熱が下がって激しい咳→咳が弱まってまた発熱→徐々に回復、という経緯で、週明け3日目(月曜から仕事だった)にしてようやく通常に戻ってきた。

 連休中で医者も休みだろうし、まあ風邪だろうから市販薬で直すか、と、妻に頼んでドラッグストアで薬を調達してきてもらった。

 まずは、総合感冒薬の PL 顆粒。「いろんな症状に効く」、つまり「どれも大して効かない」ということでもあるようだけど、医者に行ってもいつも処方されるので、まあ持っておいた方がいいのかな。

20190508-1.png

 私はすぐに喉をやられて、咳で寝られないことが多いので、咳止めも買ってきてもらった。これでした。って、よく見たらこれも総合感冒薬じゃん。

20190508-2.png

 昔から売られている外用薬も買ってきてもらった。「ヴェポラッブ」なんですね。「プ」じゃないんだ。知らんかった。

20190508-3.png

 咳止めはどちらも役に立ってくれた。とにかく、咳の頻度が減って、多少なりとも眠れるようになるのが大きい。PL 顆粒も効いた気がする。

 私が治りかけた頃、今度は妻が調子を崩して2日、子供たちも順番に半日ぐらい寝込んだ。うつしてしまったらしい。申し訳ない。ちなみに、私はたぶん土曜日に所用で名駅に出かけた時にもらってきたんだと思う。

 そういえば、昔実家で常備していたかぜ薬は、「コデジールA錠」だった。調べてみたら、他の総合感冒薬と同様、主成分はアセトアミノフェンで、咳止めでジヒドロリン酸コデイン、あと漢方の成分が少し入っているみたい。記憶にあるのとビンのラベルが違う。モデルチェンジしたかもしれないな。

20190508-4.png

タグ:生活
posted by toshinagata at 23:01| 日記

2019年04月27日

wxLuaApp で OpenGL やってみた

 球体の表面を色分けした図を描いて GIF アニメーションにする、という案件が発生した。こういうやつです。

20190427-1.gif 20190427-2.gif

 OpenGL を使えばできそう、というのはすぐに思いついたのだが、どう実装するかでしばし悩んだ。最近の流行りで言えば WebGL なんだろうけど、少し調べてみてハードルが高そうと感じた。自分の OpenGL の知識が相当古いところで止まっているのが原因かもしれず、本当はそちらをアップデートするのが正攻法なのだが、今回はとにかく早く結果が欲しい。

 そこで、Molby のコードを流用することにした。さすがに C で書くのはどうかと思ったので、最近のマイブームである wxLuaApp で OpenGL に挑戦。実はこれが結構大変でありまして、WebGL を使ったほうが未来につながったかもと 15% ぐらいは思ったりしている。

sinCache = {}
sinCacheSect = 0
idle_count = 0
phase = 0
mode = 0
cflag = false
modefunc = function () return 1 end

function OnIdle(event, canvas)
  local max_count = 32
  if mode < 9 and idle_count < max_count then
    if idle_count == 0 then
      if mode == 0 then
        modefunc = function (x, y, z) return 1 end
      elseif mode == 1 then
        modefunc = function (x, y, z) return x end
      elseif mode == 2 then
        modefunc = function (x, y, z) return -y end
      elseif mode == 3 then
        modefunc = function (x, y, z) return z end
      elseif mode == 4 then
        modefunc = function (x, y, z) return 2 * z * z - x * x - y * y end
      elseif mode == 5 then
        modefunc = function (x, y, z) return 2 * z * x end
      elseif mode == 6 then
        modefunc = function (x, y, z) return -2 * y * z end
      elseif mode == 7 then
        modefunc = function (x, y, z) return x * x - y * y end
      elseif mode == 8 then
        modefunc = function (x, y, z) return -2 * x * y end
      end
    end
    CaptureCanvas(idle_count, max_count, mode, cflag)
    if cflag then
      idle_count = idle_count + 1
      if idle_count == max_count then
        idle_count = 0
        mode = mode + 1
      end
    end
    cflag = not cflag
  end
end

function ColoredVertex(c, r, x, y, z)
  local rgba
  local y2 = modefunc(x, y, z) * math.cos(phase)
  if y2 >= 0 then
    rgba = {(1 - y2) * 0.8, (1 - y2) * 0.8, 1 - (1 - y2) * 0.2, 1}
  else
    rgba = {1 - (1 + y2) * 0.2, (1 + y2) * 0.8, (1 + y2) * 0.8, 1}
  end
  gl.Material(gl.FRONT_AND_BACK, gl.DIFFUSE, rgba);
  gl.Vertex(r * x + c[1], r * y + c[2], r * z + c[3])
end

function DrawSphere(c, r, sect)
  local m = math.floor(sect / 4)
  local n = m * 4
  if sinCacheSect ~= n then
    sinCacheSect = n
    for i = 1, m * 5 + 2 do
      sinCache[i] = math.sin(math.pi * 2 / n * (i - 1))
    end
  end
  local s = sinCache
  for i = 1, n + 1 do
    gl.Begin(gl.QUAD_STRIP)
    for j = 1, n / 2 do
      gl.Normal(s[j] * s[i + m], s[j] * s[i], s[j + m])
      ColoredVertex(c, r, s[j] * s[i + m], s[j] * s[i], s[j + m])
      gl.Normal(s[j] * s[i + 1 + m], s[j] * s[i + 1], s[j + m])
      ColoredVertex(c, r, s[j] * s[i + 1 + m], s[j] * s[i + 1], s[j + m])
    end
    gl.End()
  end
  gl.Begin(gl.TRIANGLE_FAN)
  gl.Normal(0, 0, 1)
  ColoredVertex(c, r, 0, 0, 1)
  for i = n + 1, 1, -1 do
    gl.Normal(s[2] * s[i + m], s[2] * s[i], s[2 + m])
    ColoredVertex(c, r, s[2] * s[i + m], s[2] * s[i], s[2 + m])
  end
  gl.End()
  gl.Begin(gl.TRIANGLE_FAN)
  gl.Normal(0, 0, -1)
  ColoredVertex(c, r, 0, 0, -1)
  for i = 1, n + 1 do
    gl.Normal(s[2] * s[i + m], s[2] * s[i], -s[2 + m])
    ColoredVertex(c, r, s[2] * s[i + m], s[2] * s[i], -s[2 + m])
  end
  gl.End()
end

function DrawModel()
  gl.MatrixMode(gl.MODELVIEW)
  gl.LoadIdentity()
  gl.Translate(0, 0, -1)
  gl.Rotate(130, 1, 0, 0)
  gl.Rotate(-45, 0, 0, 1)
  gl.Material(gl.FRONT_AND_BACK, gl.DIFFUSE, {1, 0, 1, 1});
  gl.Enable(gl.NORMALIZE)
  DrawSphere({0, 0, 0}, 0.85, 48)
end

function CaptureCanvas(n, m, mode, cflag)
  phase = 3.1415926 * 2 * n / m
  canvas:Refresh()
  canvas:Update()
  if not cflag then return end
  canvas.context:SetCurrent(canvas)
  capture = gl.ReadPixels(0, 0, 120, 120, gl.RGBA)
  data = {}
  alpha = {}
  for i = 1, #capture do
    capture[i] = math.floor(capture[i] * 255 + 0.5)
  end
  local j = 0
  for y = 1, 120 do
    for x = 1, 120 do
      local i = ((120 - y) * 120 + x - 1) * 4 + 1
      local j = (y - 1) * 120 + x
      data[j * 3 + 1] = capture[i]
      data[j * 3 + 2] = capture[i + 1]
      data[j * 3 + 3] = capture[i + 2]
      alpha[j + 1] = capture[i + 3]
    end
  end
  image = wx.wxImage(120, 120)
  datastr = string.fromtable(data)
  alphastr = string.fromtable(alpha)
  image:SetData(datastr)
  image:SetAlpha(alphastr)
  image:SaveFile(string.format("sample%d_%02d.png", mode, n))
end

function OnPaint(event, canvas)
  local dc = wx.wxPaintDC(canvas)
  if not canvas.is_initialized then
    canvas.context = wx.wxGLContext(canvas)
    canvas.context:SetCurrent(canvas)
    sz = canvas:GetClientSize()
    gl.Viewport(0, 0, sz.x, sz.y)
    gl.Enable(gl.DEPTH_TEST)
    gl.Enable(gl.LIGHTING)
    gl.LightModel(gl.LIGHT_MODEL_AMBIENT, {0.8, 0.8, 0.8, 1.0})
    gl.Light(gl.LIGHT0, gl.DIFFUSE, {1, 1, 1, 1})
    gl.Enable(gl.LIGHT0)
    gl.Light(gl.LIGHT1, gl.AMBIENT, {0.4, 0.4, 0.4, 1})
    gl.Enable(gl.LIGHT1)
    gl.Enable(gl.BLEND)
    gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
    canvas.is_initialized = true
  end
  canvas.context:SetCurrent(canvas)
  gl.ClearColor(0, 0, 0, 0)
  gl.Clear(bit.bor(gl.COLOR_BUFFER_BIT, gl.DEPTH_BUFFER_BIT))
  DrawModel()
  gl.Flush()
  canvas:SwapBuffers()
  dc:delete()
end

function main()
  --  フレームを作成
  frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, "", wx.wxPoint(50, 50), wx.wxSize(120, 200))
  frame:SetClientSize(120, 120)
  --  GLCanvas を作成
  canvas = wx.wxGLCanvas(frame, wx.wxID_ANY, {}, wx.wxDefaultPosition, wx.wxSize(120, 120), 0, "GLCanvas")
  canvas.is_initialized = false
  --  イベントを接続
  canvas:Connect(wx.wxEVT_PAINT, function (event) OnPaint(event, canvas) end)
  canvas:Connect(wx.wxEVT_IDLE, function (event) OnIdle(event, canvas) end)
  frame:Show(true)
end

main()
posted by toshinagata at 00:55| 日記

2019年04月14日

ウメとナツミカン

 ウメの花が終わった後、実がたくさんついている。

20190414-1.jpg

20190414-2.jpg

 実を収穫することを目指すのかどうか、ちょっと悩ましいところ。このウメは、実ウメとして植えたものではないので、大した実は成らないような気がする。でも、これだけ実がついていると、落ちるに任せるのもちょっともったいない気もするんだよな。一応実を間引いて、根元に肥料はあげておいた。

 一方、ナツミカンの方は、今のところ葉芽ばかり出てきている。芽吹いてくる前に大きく剪定したので、木が葉を伸ばす方に向いてしまったかも。今年成りすぎたので来年は実は少ない年だけど、ゼロはさびしいな。なんとかこれから少しでも花芽が出てきてくれるといいのだけど。

20190414-3.jpg

タグ:園芸
posted by toshinagata at 15:57| 日記
email.png
Powered by さくらのブログ