Microsoft Small Basic

Program Listing: QWF833
' Parallelogram
' Version 0.1
' Copyright © 2019 Nonki Takahashi. The MIT License.
' Last update 2019-01-03

GraphicsWindow.Title = "Parallelogram | Toggle Shapes opacity with mouse"
Init()
pw = 0
pc = "Black"
While "True"
i = 0
bc = "LightGray"
width = Math.GetRandomNumber(400) + 100
height = Math.GetRandomNumber(200) + 100
x = Math.GetRandomNumber(gw - width - 20) + 10
y = Math.GetRandomNumber(gh - height - 20) + 10
angle = 0
AddRectangle()
ratio = Math.GetRandomNumber(width) / height
_x = x
_y = y
x = _x + height * ratio - 4
y = _y - 8
angle = 180
x1 = 4
y1 = 0
x2 = 0
y2 = 8
x3 = 8
y3 = 8
AddTriangle()
x = _x
y = _y
angle = 0
bc = "Brown"
AddParallelogram()
Delay()
RemoveShapes()
EndWhile

Sub AddParallelogram
' param x, y - the left top coordinate of the parallelogram
' param width, height - the size of the parallelogram
' param ratio - the delta x per height
GraphicsWindow.PenColor = pc
GraphicsWindow.PenWidth = pw
_x = x
_y = y
_width = width
_height = height
r2 = ratio * ratio
l2 = Math.SquareRoot(1 + r2)
If ratio <= (1 / Math.SquareRoot(3)) Then
If (3 * ratio) <= (width / height) Then
_bc = bc
bc = "Black"
x = 10
y = 10
txt = "Case 1"
angle = 0
AddText()
bc = _bc
x1 = Math.Round(ratio * height)
y1 = 0
x2 = 0
y2 = height
x3 = x1 * 2
y3 = height
x = _x
y = _y
angle = 0
AddTriangle()
x = x + width - 2 * x1
angle = 180
AddTriangle()
x = _x + x1
width = width - 2 * x1
AddRectangle()
Else
_bc = bc
bc = "Black"
x = 10
y = 10
txt = "Case 2"
angle = 0
AddText()
bc = _bc
_a = Math.ArcTan(1 / ratio)
a = Math.Round(Math.GetDegrees(_a) * 100) / 100
l3 = width / height - ratio
l1 = 2 * l3 * Math.Cos(_a)
h1 = l3 * Math.Sin(_a)
x1 = Math.Round(l1 * height * 50) / 100
y1 = 0
x2 = 0
y2 = Math.Round(h1 * height * 100) / 100
x3 = x1 * 2
y3 = y2
x = _x + Math.Round((l3 / 2 + l1 / 4 * Math.Cos(_a) - l1 / 2) * height * 100) / 100
y = _y + Math.Round((1 - l1 / 4 * Math.Sin(_a) - h1 / 2) * height * 100) / 100
angle = 180 - a
AddTriangle()
x = _x + width + Math.Round((-l3 / 2 - l1 / 4 * Math.Cos(_a) - l1 / 2) * height * 100) / 100
y = _y + Math.Round((l1 / 4 * Math.Sin(_a) - h1 / 2) * height * 100) / 100
angle = -a
AddTriangle()
width = Math.Round((l2 - l1 / 2) * _height * 100) / 100
height = Math.Round(h1 * _height * 100) / 100
x = _x + Math.Round((_width - width) * 50) / 100
y = _y + Math.Round((_height - height) * 50) / 100
AddRectangle()
EndIf
Else
If (l2 + ratio) <= (width / height) Then
_bc = bc
bc = "Black"
x = 10
y = 10
txt = "Case 3"
angle = 0
AddText()
bc = _bc
l1 = Math.SquareRoot(1 + Math.Power(l2 - ratio, 2))
h1 = Math.SquareRoot(l2 * l2 - l1 * l1 / 4)
_a = Math.ArcTan(h1 / (l1 / 2))
a = Math.Round(Math.GetDegrees(_a) * 100) / 100
x1 = Math.Round(l1 * height * 50) / 100
y1 = 0
x2 = 0
y2 = Math.Round(h1 * height * 100) / 100
x3 = x1 * 2
y3 = y2
x = _x + Math.Round((l2 / 2 * height - x1 / 2 * Math.Cos(_a)) * 100) / 100 - x1
y = _y + Math.Round((height - x1 / 2 * Math.Sin(_a) - y2 / 2) * 100) / 100
angle = a + 180
AddTriangle()
x = _x + width - Math.Round((l2 / 2 * height - x1 / 2 * Math.Cos(_a)) * 100) / 100 - x1
y = _y + Math.Round((x1 / 2 * Math.Sin(_a) - y2 / 2)* 100) / 100
angle = a
AddTriangle()
x = _x + Math.Round(ratio * height * 100) / 100
y = _y
width = width - 2 * Math.Round(ratio * height * 100) / 100
angle = 0
AddRectangle()
Else
_bc = bc
bc = "Black"
x = 10
y = 10
txt = "Case 4"
angle = 0
AddText()
bc = _bc
_b = Math.ArcTan(1 / ratio)
_a = (Math.Pi - _b) / 2
a = Math.Round(Math.GetDegrees(_a) * 100) / 100
l3 = width / height - ratio
l1 = 2 * l3 * Math.Cos(_a)
h1 = l3 * Math.Sin(_a)
x1 = Math.Round(l1 * height * 50) / 100
y1 = 0
x2 = 0
y2 = Math.Round(h1 * height * 100) / 100
x3 = x1 * 2
y3 = y2
x = _x + Math.Round((l3 / 2 - l1 / 4 * Math.Cos(_a) - l1 / 2) * height * 100) / 100
y = _y + Math.Round((1 - l1 / 4 * Math.Sin(_a) - h1 / 2) * height * 100) / 100
angle = 180 + a
AddTriangle()
x = _x + Math.Round((ratio + l3 / 2 + l1 / 4 * Math.Cos(_a) - l1 / 2) * height * 100) / 100
y = _y + Math.Round((l1 / 4 * Math.Sin(_a) - h1 / 2) * height * 100) / 100
angle = a
AddTriangle()
width = Math.Round((l2 - l3 * Math.Cos(_b)) * _height * 100) / 100
height = Math.Round(l3 * Math.Sin(_b) * _height * 100) / 100
x = _x + Math.Round((_width - width) * 50) / 100
y = _y + Math.Round((_height - height) * 50) / 100
angle = -Math.Round(Math.GetDegrees(_b) * 100) / 100
AddRectangle()
EndIf
EndIf
x = _x
y = _y
width = _width
height = _height
EndSub

Sub AddRectangle
i = i + 1
GraphicsWindow.PenColor = pc
GraphicsWindow.PenWidth = pw
GraphicsWindow.BrushColor = bc
shp[i] = Shapes.AddRectangle(width, height)
Shapes.Move(shp[i], x, y)
Shapes.Rotate(shp[i], angle)
Shapes.SetOpacity(shp[i], op)
EndSub

Sub AddText
i = i + 1
GraphicsWindow.BrushColor = bc
GraphicsWindow.FontSize = fs
GraphicsWindow.FontBold = fb
GraphicsWindow.FontItalic = fi
GraphicsWindow.FontName = fn
shp[i] = Shapes.AddText(txt)
Shapes.Move(shp[i], x, y)
Shapes.Rotate(shp[i], angle)
Shapes.SetOpacity(shp[i], op)
EndSub

Sub AddTriangle
i = i + 1
GraphicsWindow.PenColor = pc
GraphicsWindow.PenWidth = pw
GraphicsWindow.BrushColor = bc
shp[i] = Shapes.AddTriangle(x1, y1, x2, y2, x3, y3)
Shapes.Move(shp[i], x, y)
Shapes.Rotate(shp[i], angle)
Shapes.SetOpacity(shp[i], op)
EndSub

Sub Delay
t = Clock.ElapsedMilliseconds
mouseDown = "False"
While Clock.ElapsedMilliseconds < (t + 3000)
If mouseDown Then
If op = 100 Then
op = 70
Else
op = 100
EndIF
For i = 1 To Array.GetItemCount(shp)
Shapes.SetOpacity(shp[i], op)
EndFor
mouseDown = "False"
EndIf
EndWhile
EndSub

Sub DumpParallelogram
TextWindow.WriteLine("x=" + x)
TextWindow.WriteLine("y=" + y)
TextWindow.WriteLine("width=" + width)
TextWindow.WriteLine("height=" + height)
TextWindow.WriteLine("angle=" + angle)
TextWindow.WriteLine("ratio=" + ratio)
EndSub

Sub DumpTriangle
TextWindow.WriteLine("x=" + x)
TextWindow.WriteLine("y=" + y)
TextWindow.WriteLine("x1=" + x1)
TextWindow.WriteLine("y1=" + y1)
TextWindow.WriteLine("x2=" + x2)
TextWindow.WriteLine("y2=" + y2)
TextWindow.WriteLine("x3=" + x3)
TextWindow.WriteLine("y3=" + y3)
TextWindow.WriteLine("angle=" + angle)
TextWindow.Pause()
EndSub

Sub Init
Not = "True=False;False=True;"
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.PenWidth = 0
op = 100
fn = "Trebuchet MS"
fs = 20
fb = "True"
fi = "False"
GraphicsWindow.MouseDown = OnMouseDown
EndSub

Sub OnMouseDown
mouseDown = "True"
EndSub

Sub RemoveShapes
n = Array.GetItemCount(shp)
For i = 1 To n
Shapes.Remove(shp[i])
shp[i] = ""
EndFor
EndSub

Sub Math_CartesianToPolar
' Math | convert cartesian coodinate To polar coordinate
' param x, y - cartesian coordinate
' return r, a - polar coordinate
r = Math.SquareRoot(x * x + y * y)
If x = 0 And y > 0 Then
a = 90 ' [degree]
ElseIf x = 0 And y < 0 Then
a = -90
ElseIf x = 0 Then
a = 0
Else
a = Math.ArcTan(y / x) * 180 / Math.Pi
EndIf
If x < 0 Then
a = a + 180
ElseIf x >= 0 And y < 0 Then
a = a + 360
EndIf
EndSub