Supercosine 0.1.0

前回使ったスーパー楕円をパラメーター $\theta$ で表した式、 $$\DeclareMathOperator{\sgn}{sgn} x = \sgn(\cos \theta) \; a \; \left| \cos \theta \right| ^{\frac{2}{n}} $$ $$ y = \sgn(\sin \theta ) \; b \; \left| \sin \theta \right| ^{\frac{2}{n}} $$ をそれぞれグラフにします。

実行結果

Small Basic オンラインで実行したスクリーンショットを以下に示します。 $a = 1$、$b = 1$ に固定しました。 まずは $x$ の式を仮にスーパーコサインと呼ぶことにします。グラフは横軸が $\theta$ で縦軸が $x$ です。 $n \lt 0.5$ のときは $\theta = -\pi / 2$ 付近の傾きが $0$ になり、 $n = 2$ のときは $\cos \theta$ と同じ傾き $1$、$n > 2$ で傾きが $1$ 以上になっていきます。

次に $y$ の式を仮にスーパーサインと呼ぶことにします。グラフの縦軸は $y$ になります。スーパーコサインと同様、 $n \lt 0.5$ のときは $\theta = 0$ 付近の傾きが $0$ になり、 $n = 2$ のときは $\cos \theta$ と同じ傾き $1$、$n > 2$ で傾きが $1$ 以上になっていきます。$\cos$ と $\sin$ の関係と同じように、 スーパーコサインとスーパーサインも $\theta$(位相)を $\pi / 2$ (90°)ずらした形になっています。

ソース

Supercosine.txt

今回は座標系が $(x, y)$ ではなく、$(\theta, x)$ になっているので、変数名を それに合わせました。 $\theta$ の最小値と最大値を画面のちょっと外側に設定して計算しました。

' Supercosine
' Version 0.1.0
' Copyright © 2020 Nonki Takahshi.  The MIT License.
' Last update 2020-09-02

scale = 120
DrawGrid()
a = 1
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(40, 10, "a = " + a)
b = 1
GraphicsWindow.DrawText(40, 30, "b = " + b)
shN = Shapes.AddText("")
Shapes.Move(shN, 40, 50)
While "True"
    For n = 0.25 To 4 Step 0.25
        Shapes.SetText(shN, "n = " + n)
        For i = 1 To nL
            Shapes.Remove(shL[i])
        EndFor
        GraphicsWindow.PenWidth = 2
        GraphicsWindow.PenColor = "Black"
        DrawSuperCos()
        keyDown = "False"
        Program.Delay(500)
    EndFor
EndWhile

Sub DrawSuperCos
    ' param gxo, gyo - center position in the graphics window
    ' param a, b - major and minor semi axis
    ' param n
    ' param scale
    nL = 0
    shL = ""
    For θ = θ1 To θ2 Step dθ
        SuperCos()
        Map()
        gx2 = gx
        gy2 = gy
        If θ <> θ1 Then
            nL = nL + 1
            shL[nL] = Shapes.AddLine(gx1, gy1, gx2, gy2)
        EndIf
        gx1 = gx2
        gy1 = gy2
    EndFor
EndSub

Sub DrawGrid
    gw = GraphicsWindow.Width
    gh = GraphicsWindow.Height
    gxo = gw / 2
    gyo = gh / 2
    fn = GraphicsWindow.FontName
    If (fn = "Tahoma") Or (fn = "Segoe UI") Then
        c10 = "#33009999"
        c100 = "#66009999"
        bc = "#00CCCC"
    Else    ' for SBO
        c10 = "#00999933"
        c100 = "#00999966"
        bc = "#00CCCC"
    EndIf
    GraphicsWindow.FontName = "Courier New"
    GraphicsWindow.FontSize = 14
    GraphicsWindow.BrushColor = bc
    dθ = 0.1
    dx = -0.1
    gx = Math.Remainder(gw / 2, dθ * scale) - dθ * scale
    gy = Math.Remainder(gh / 2, dx * scale)
    MapInv()
    θ1 = θ
    x1 = x
    gx = gw - Math.Remainder(gw / 2, dθ * scale) + dθ * scale
    gy = gh - Math.Remainder(gh / 2, dx * scale)
    MapInv()
    θ2 = θ
    x2 = x
    For θ = θ1 To θ2 Step dθ
        Map()
        rem = Math.Remainder(θ, 1)
        If rem = 0.0 Then
            GraphicsWindow.PenColor = c100
            GraphicsWindow.DrawText(gx + 2, gh / 2, θ)
        Else
            GraphicsWindow.PenColor = c10
        EndIf
        GraphicsWindow.DrawLine(gx, 0, gx, gh)
    EndFor
    For x = x1 To x2 Step dx
        Map()
        If Math.Remainder(x, 1) = 0.0 Then
            GraphicsWindow.PenColor = c100
            If x <> 0 Then
                GraphicsWindow.DrawText(gw / 2 + 2, gy, x)
            EndIf
        Else
            GraphicsWindow.PenColor = c10
        EndIf
        GraphicsWindow.DrawLine(0, gy, gw, gy)
    EndFor
EndSub

Sub Map
    gx = gxo + scale * θ
    gy = gyo - scale * x
EndSub

Sub MapInv
    θ = (gx - gxo) / scale
    x = -(gy - gyo) / scale
EndSub

Sub SuperCos
    abs = Math.Abs(Math.Cos(θ))
    If abs = 0 Then
        sgn = 0
    Else
        sgn = Math.Cos(θ) / abs
    EndIf
    x = sgn * a * Math.Power(abs, 2 / n)
EndSub

Supersine.txt

上記の Supercosine.txt との違う部分をハイライト表示しました。5行変えただけです。

' Supersine
' Version 0.1.0
' Copyright © 2020 Nonki Takahshi.  The MIT License.
' Last update 2020-09-02

scale = 120
DrawGrid()
a = 1
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(40, 10, "a = " + a)
b = 1
GraphicsWindow.DrawText(40, 30, "b = " + b)
shN = Shapes.AddText("")
Shapes.Move(shN, 40, 50)
While "True"
    For n = 0.25 To 4 Step 0.25
        Shapes.SetText(shN, "n = " + n)
        For i = 1 To nL
            Shapes.Remove(shL[i])
        EndFor
        GraphicsWindow.PenWidth = 2
        GraphicsWindow.PenColor = "Black"
        DrawSuperSin()
        keyDown = "False"
        Program.Delay(500)
    EndFor
EndWhile

Sub DrawSuperSin
    ' param gxo, gyo - center position in the graphics window
    ' param a, b - major and minor semi axis
    ' param n
    ' param scale
    nL = 0
    shL = ""
    For θ = θ1 To θ2 Step dθ
        SuperSin()
        Map()
        gx2 = gx
        gy2 = gy
        If θ <> θ1 Then
            nL = nL + 1
            shL[nL] = Shapes.AddLine(gx1, gy1, gx2, gy2)
        EndIf
        gx1 = gx2
        gy1 = gy2
    EndFor
EndSub

Sub DrawGrid
    gw = GraphicsWindow.Width
    gh = GraphicsWindow.Height
    gxo = gw / 2
    gyo = gh / 2
    fn = GraphicsWindow.FontName
    If (fn = "Tahoma") Or (fn = "Segoe UI") Then
        c10 = "#33009999"
        c100 = "#66009999"
        bc = "#00CCCC"
    Else    ' for SBO
        c10 = "#00999933"
        c100 = "#00999966"
        bc = "#00CCCC"
    EndIf
    GraphicsWindow.FontName = "Courier New"
    GraphicsWindow.FontSize = 14
    GraphicsWindow.BrushColor = bc
    dθ = 0.1
    dx = -0.1
    gx = Math.Remainder(gw / 2, dθ * scale) - dθ * scale
    gy = Math.Remainder(gh / 2, dx * scale)
    MapInv()
    θ1 = θ
    x1 = x
    gx = gw - Math.Remainder(gw / 2, dθ * scale) + dθ * scale
    gy = gh - Math.Remainder(gh / 2, dx * scale)
    MapInv()
    θ2 = θ
    x2 = x
    For θ = θ1 To θ2 Step dθ
        Map()
        rem = Math.Remainder(θ, 1)
        If rem = 0.0 Then
            GraphicsWindow.PenColor = c100
            GraphicsWindow.DrawText(gx + 2, gh / 2, θ)
        Else
            GraphicsWindow.PenColor = c10
        EndIf
        GraphicsWindow.DrawLine(gx, 0, gx, gh)
    EndFor
    For x = x1 To x2 Step dx
        Map()
        If Math.Remainder(x, 1) = 0.0 Then
            GraphicsWindow.PenColor = c100
            If x <> 0 Then
                GraphicsWindow.DrawText(gw / 2 + 2, gy, x)
            EndIf
        Else
            GraphicsWindow.PenColor = c10
        EndIf
        GraphicsWindow.DrawLine(0, gy, gw, gy)
    EndFor
EndSub

Sub Map
    gx = gxo + scale * θ
    gy = gyo - scale * x
EndSub

Sub MapInv
    θ = (gx - gxo) / scale
    x = -(gy - gyo) / scale
EndSub

Sub SuperSin
    abs = Math.Abs(Math.Sin(θ))
    If abs = 0 Then
        sgn = 0
    Else
        sgn = Math.Sin(θ) / abs
    EndIf
    x = sgn * b * Math.Power(abs, 2 / n)
EndSub

Copyright © 2020 たかはしのんき. All rights reserved.