Microsoft Small Basic

Program Listing: TJB764
' Cartesian and Polar Coordinates
' Version 0.1
' Copyright © 2016 Nonki Takahashi. The MIT License.
' Last update 2016-02-20
'
GraphicsWindow.Title = "Cartesian and Polar Coordinates 0.1"
CRLF = Text.GetCharacter(13) + Text.GetCharacter(10)
DIGITS = "0123456789-"
Not = "True=False;False=True;"
Form()
x = 300
y = 100
While "True"
buf = "Click to draw vector a." + CRLF + CRLF
param = "color=#99FFFF;gap=10;"
DrawGrid()
param = "color=#00FFFF;gap=100;"
DrawGrid()
param = "a=(" + x + "," + y + ");"
Vector_Calc()
vector = "a"
Vector_Draw()
Vector_Print()
param = "o=(0,0);"
Vector_Calc()
param = "b=(" + r + ",0);"
param = "c=o;s=b;e=a;color=#33000000;"
FillFan()
While Not[mouseDown]
Program.Delay(200)
EndWhile
x = Math.Round(GraphicsWindow.MouseX / 10) * 10
y = Math.Round(GraphicsWindow.MouseY / 10) * 10
mouseDown = "False"
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FillRectangle(0, 0, gw, gh)
EndWhile
Sub DrawGrid
Stack.PushValue("local", x)
Stack.PushValue("local", y)
GraphicsWindow.PenColor = param["color"]
For x = 0 To gw Step param["gap"]
GraphicsWindow.DrawLine(x, 0, x, gh)
EndFor
For y = 0 To gh Step param["gap"]
GraphicsWindow.DrawLine(0, y, gw, y)
EndFor
y = Stack.PopValue("local")
x = Stack.PopValue("local")
EndSub
Sub FillFan
' param["c"] - the center of the fan
' param["s"] - the start point
' param["e"] - the end point
' param["color"] - brush color to fill the fan
Stack.PushValue("local", param)
_p1 = param["c"]
_s = param["s"]
_e = param["e"]
_color = param["color"]
param="cs="+ _s + "-" + _p1 + ";"
Vector_Calc()
x = element["csx"]
y = element["csy"]
Math_CartesianToPolar()
as = a
param="ce="+ _e + "-" + _p1 + ";"
Vector_Calc()
x = element["cex"]
y = element["cey"]
Math_CartesianToPolar()
ae = a
For a = as To ae Step 5
x = r * Math.Cos(Math.GetRadians(a))
y = r * Math.Sin(Math.GetRadians(a))
param = "_p3=(" + x + "," + y + ");"
Vector_Calc()
If as < a Then
param = "p1=" + _p1 + ";p2=_p2;p3=_p3;color=" + _color + ";"
FillTriangle()
EndIf
' _p2 = _p3
element["_p2x"] = element["_p3x"]
element["_p2y"] = element["_p3y"]
EndFor
x = r * Math.Cos(Math.GetRadians(ae))
y = r * Math.Sin(Math.GetRadians(ae))
param = "_p3=(" + x + "," + y + ");"
Vector_Calc()
param = "p1=" + _p1 + ";p2=_p2;p3=_p3;color=" + _color + ";"
FillTriangle()
param = Stack.PopValue("local")
EndSub
Sub FillTriangle
' param["p1"] - the first point
' param["p2"] - the second point
' param["p3"] - the third point
' param["color"] - brush color to fill the triangle
GraphicsWindow.BrushColor = param["color"]
_x1 = element[param["p1"] + "x"]
_y1 = element[param["p1"] + "y"]
_x2 = element[param["p2"] + "x"]
_y2 = element[param["p2"] + "y"]
_x3 = element[param["p3"] + "x"]
_y3 = element[param["p3"] + "y"]
GraphicsWindow.FillTriangle(_x1, _y1, _x2, _y2, _x3, _y3)
EndSub
Sub Form
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.FontName = "Courier New" ' next option
GraphicsWindow.FontName = "Consolas" ' top candidate
GraphicsWindow.FontSize = 14
GraphicsWindow.PenWidth = 1
tbox = Controls.AddMultiLineTextBox(gw - 208, 10)
Controls.SetSize(tbox, 200, 250)
mouseDown = "False"
GraphicsWindow.MouseDown = OnMouseDown
EndSub
Sub OnMouseDown
mouseDown = "True"
EndSub
Sub Math_CartesianToPolar
' Math | convert Cartesian coodinate to polar coordinate
' param x, y - Cartesian coordinate
' return r, a - polar coordinate (0<=a<360)
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 ' this condition is needed for SB 1.2
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
Sub Vector_Calc
' param "v" - vector name[s]
' param["v"] - expression[s]:
' (scalar,scalar) - set vector
' vector+vector - add vectors
' vector-vector - subtract between vectors
' matrix*vector - multiply matrix and vector
' scalar*vector - multiply scalar and vector
' |vector| - get absolute value from vector
' return element - array for vector elements
Stack.PushValue("local", vector)
names = Array.GetAllIndices(param)
n = Array.GetItemCount(param)
For i = 1 To n
vector = names[i]
expr = param[names[i]]
If Text.StartsWith(expr, "|") Then
Vector_GetOp()
scalar = vector
Vector_Abs()
ElseIf Text.StartsWith(expr, "(") Then
delim = ","
Vector_GetOp()
Vector_Set()
ElseIf Text.IsSubText(expr, "+") Then
delim = "+"
Vector_GetOp()
Vector_Add()
ElseIf Text.IsSubText(expr, "*") Then
delim = "*"
Vector_GetOp()
Vector_Mul()
ElseIf Text.IsSubText(expr, "-") Then
delim = "-"
Vector_GetOp()
Vector_Sub()
EndIf
EndFor
vector = Stack.PopValue("local")
EndSub
Sub Vector_Abs
' param scalar - target scalar name
' param op[1] - vector name
' return element - array for vector elements
_x2 = Math.Power(element[op[1] + "x"], 2)
_y2 = Math.Power(element[op[1] + "y"], 2)
element[scalar] = Math.SquareRoot(_x2 + _y2)
EndSub
Sub Vector_Add
' param vector - target vector name
' param op[1], op[2] - vector names
' return element - array for vector elements
element[vector + "x"] = element[op[1] + "x"] + element[op[2] + "x"]
element[vector + "y"] = element[op[1] + "y"] + element[op[2] + "y"]
EndSub
Sub Vector_Comp
' param op[1], op[2] - operands
' return eq - "True" if operands are the same
' return ne - "True" if operands are not the same
_x1 = element[op[1] + "x"]
_y1 = element[op[1] + "y"]
_x2 = element[op[2] + "x"]
_y2 = element[op[2] + "y"]
If Math.Abs(_x1 - _x2) < 0.01 And Math.Abs(_y1 - _y2) < 0.01 Then
eq = "True"
ne = "False"
Else
eq = "False"
ne = "True"
EndIf
EndSub
Sub Vector_Draw
' param vector - target vector name
GraphicsWindow.PenColor = "Black"
GraphicsWindow.DrawLine(0, 0, element[vector + "x"], element[vector + "y"])
param = "_l=|" + vector + "|;"
Vector_Calc()
_k = -10 / element["_l"]
param = "_u=" + _k + "*" + vector + ";"
Vector_Calc()
Stack.PushValue("local", vector)
vector = "_r"
op[1] = "_u"
angle = -20
Vector_Rotate()
vector = "_l"
angle = 20
Vector_Rotate()
vector = Stack.PopValue("local")
param = "_r2=" + vector + "+_r;_l2=" + vector + "+_l;"
Vector_Calc()
GraphicsWindow.DrawLine(element[vector + "x"], element[vector + "y"], element["_r2x"], element["_r2y"])
GraphicsWindow.DrawLine(element[vector + "x"], element[vector + "y"], element["_l2x"], element["_l2y"])
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(element[vector + "x"], element[vector + "y"], vector)
EndSub
Sub Vector_GetOp
' param expr - expression
' param delim - delimiter
' return op[1], op[2] - operands
Stack.PushValue("local", expr)
If Text.StartsWith(expr, "|") Then
_abs = "True"
Else
_abs = "False"
EndIf
If Text.StartsWith(expr, "(") Or Text.StartsWith(expr, "|") Then
expr = Text.GetSubTextToEnd(expr, 2)
EndIf
If Text.EndsWith(expr, ")") Or Text.EndsWith(expr, "|") Then
len = Text.GetLength(expr)
expr = Text.GetSubText(expr, 1, len - 1)
EndIf
If _abs Then
op[1] = expr
Else
p = Text.GetIndexOf(expr, delim)
op[1] = Text.GetSubText(expr, 1, p - 1)
op[2] = Text.GetSubTextToEnd(expr, p + 1)
EndIf
expr = Stack.PopValue("local")
EndSub
Sub Vector_Mul
' param vector - target vector name
' param op[1] - scalar value or matrix name
' param op[2] - vector name
' return element - array for vector elements
If Text.IsSubText(DIGITS, Text.GetSubText(op[1], 1, 1)) Then
element[vector + "x"] = op[1] * element[op[2] + "x"]
element[vector + "y"] = op[1] * element[op[2] + "y"]
Else
element[vector + "x"] = element[op[1] + "11"] * element[op[2] + "x"] + element[op[1] + "12"] * element[op[2] + "y"]
element[vector + "y"] = element[op[1] + "21"] * element[op[2] + "x"] + element[op[1] + "22"] * element[op[2] + "y"]
EndIf
EndSub
Sub Vector_Print
' param vector - target vector name
buf = buf + vector + "=("
x = element[vector + "x"]
y = element[vector + "y"]
buf = buf + (Math.Floor(x * 100) / 100) + ","
buf = buf + (Math.Floor(y * 100) / 100) + ")" + CRLF
Math_CartesianToPolar()
buf = buf + "r=" + (Math.Floor(r * 100) / 100) + CRLF
buf = buf + "θ=" + (Math.Floor(a * 100) / 100) + "°" + CRLF
Controls.SetTextBoxText(tbox, buf)
EndSub
Sub Vector_Rotate
' param vector - target vector name
' param op[1] - original vector name
' param angle - angle to rotate
' return element - array for vector elements
Stack.PushValue("local", param)
Stack.PushValue("local", vector)
Stack.PushValue("local", op)
_a = Math.GetRadians(angle)
element["_R11"] = Math.Cos(_a)
element["_R12"] = -Math.Sin(_a)
element["_R21"] = Math.Sin(_a)
element["_R22"] = Math.Cos(_a)
param = vector + "=_R*" + op[1] + ";"
Vector_Calc()
op = Stack.PopValue("local")
vector = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub Vector_Set
' param vector - vector name
' param op[1], op[2] - x, y coordinate
' return element - array for vector elements
element[vector + "x"] = op[1]
element[vector + "y"] = op[2]
EndSub
Sub Vector_Sub
' param vector - target vector name
' param op[1], op[2] - vector names
' return element - array for vector elements
element[vector + "x"] = element[op[1] + "x"] - element[op[2] + "x"]
element[vector + "y"] = element[op[1] + "y"] - element[op[2] + "y"]
EndSub