Microsoft Small Basic

Program Listing: HBN459
' Lissajous Curve 0.1
' Copyright (c) 2013 Nonki Takahashi. All rights reserved.
'
' History
' 0.1 2013-08-04 Created.
'
gw = 640
gh = 480
GraphicsWindow.Title = "Lissagjous Curve 0.1 - Hit A or B key."
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BackgroundColor = "Black"
GraphicsWindow.BrushColor = "SteelBlue"
param="x=40;y=20;width=450;height=440;border-radius=20;"
FillRoundRectangle()
r = 150
x0 = gw / 2 - r / 2 + 20
y0 = gh / 2
DrawGrid()
t = 0
a = 3
b = 2
delta = Math.Pi / 2
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FontSize = 24
texta = Shapes.AddText("a = " + a)
Shapes.Move(texta, 510, 50)
textb = Shapes.AddText("b = " + b)
Shapes.Move(textb, 510, 80)
textd = Shapes.AddText("δ = π/2")
Shapes.Move(textd, 510, 110)
dt = 1 / 30
i = 0
imax = 300
GraphicsWindow.PenColor = "MediumAquamarine"
GraphicsWindow.PenWidth = 2
GraphicsWindow.KeyDown = OnKeyDown
While "True"
Lissajous()
x1 = x
y1 = y
If 0 < t Then
i = i + 1
If imax < i Then
i = 1
EndIf
If obj[i] <> "" Then
Shapes.Remove(obj[i])
EndIf
obj[i] = Shapes.AddLine(x1, y1, x2, y2)
Program.Delay(1)
EndIf
t = t + dt
x2 = x1
y2 = y1
EndWhile
Sub OnKeyDown
key = GraphicsWindow.LastKey
If key = "A" Then
a = a + 1
If 5 < a Then
a = 1
EndIf
Shapes.SetText(texta, "a = " + a)
ElseIf key = "B" Then
b = b + 1
If 5 < b Then
b = 1
EndIf
Shapes.SetText(textb, "b = " + b)
EndIf
EndSub
Sub Lissajous
x = x0 + r * Math.Cos(a * t + delta)
y = y0 - r * Math.Sin(b * t)
EndSub
Sub DrawGrid
GraphicsWindow.PenWidth = 1
GraphicsWindow.PenColor = "Black"
For y = y0 - (r / 2) * 2 To y0 + (r / 2) * 2 Step r / 2
GraphicsWindow.DrawLine(40, y 490, y)
EndFor
For x = x0 - (r / 2) * 2 To x0 + (r / 2) * 2 Step r / 2
GraphicsWindow.DrawLine(x, 20, x, 460)
EndFor
EndSub
Sub DrawRoundRectangle
Stack.PushValue("local", param)
Stack.PushValue("local", local)
local = param
param = ""
param["r"] = local["border-radius"]
If (local["width"] / 2 < param["r"]) Or (local["height"] / 2 < param["r"]) Then
param["r"] = Math.Min(local["width"] / 2, local["height"] / 2)
EndIf
param["da"] = 5
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 180
param["a2"] = 270
DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"], local["x"] + local["width"] - param["r"], local["y"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 270
param["a2"] = 360
DrawArc()
GraphicsWindow.DrawLine(local["x"] + local["width"], local["y"] + param["r"], local["x"] + local["width"], local["y"] + local["height"] - param["r"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 0
param["a2"] = 90
DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"] + local["height"], local["x"] + local["width"] - param["r"], local["y"] + local["height"])
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 90
param["a2"] = 180
DrawArc()
GraphicsWindow.DrawLine(local["x"], local["y"] + param["r"], local["x"], local["y"] + local["height"] - param["r"])
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub FillRoundRectangle
Stack.PushValue("local", param)
If (param["width"] / 2 < param["border-radius"]) Or (param["height"] / 2 < param["border-radius"]) Then
param["border-radius"] = Math.Min(param["width"] / 2, param["height"] / 2)
EndIf
GraphicsWindow.FillEllipse(param["x"], param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"] + param["border-radius"], param["y"], param["width"] - param["border-radius"] * 2, param["height"])
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"], param["y"] + param["border-radius"], param["width"], param["height"] - param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"], param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
param = Stack.PopValue("local")
EndSub
Sub DrawArc
Stack.PushValue("local", param)
Stack.PushValue("local", local)
Stack.PushValue("local", a)
local = param
param = ""
local["pw"] = GraphicsWindow.PenWidth
local["pc"] = GraphicsWindow.PenColor
local["bc"] = GraphicsWindow.BrushColor
GraphicsWindow.BrushColor = local["pc"]
local["r1"] = local["r"] - local["pw"] / 2
local["r2"] = local["r"] + local["pw"] / 2
For a = local["a1"] To local["a2"] Step local["da"]
local["rad"] = Math.GetRadians(a)
param["x1"] = local["x"] + local["r1"] * Math.Cos(local["rad"])
param["y1"] = local["y"] + local["r1"] * Math.Sin(local["rad"])
param["x2"] = local["x"] + local["r2"] * Math.Cos(local["rad"])
param["y2"] = local["y"] + local["r2"] * Math.Sin(local["rad"])
If local["a1"] < a Then
FillQuadrangle()
EndIf
param["x4"] = param["x1"]
param["y4"] = param["y1"]
param["x3"] = param["x2"]
param["y3"] = param["y2"]
EndFor
GraphicsWindow.BrushColor = local["bc"]
a = Stack.PopValue("local")
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub FillQuadrangle
GraphicsWindow.FillTriangle(param["x1"], param["y1"], param["x2"], param["y2"], param["x3"], param["y3"])
GraphicsWindow.FillTriangle(param["x3"], param["y3"], param["x4"], param["y4"], param["x1"], param["y1"])
EndSub