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
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 SB_RotateWorkaround
' Small Basic | Rotate workaround for Silverlight
' param x, y - original coordinate
' param alpha - angle [radian]
' returns x, y - workaround coordinate
If shape[i]["func"] = "tri" Then
x1 = -Math.Floor(shape[i]["x3"] / 2)
y1 = -Math.Floor(shape[i]["y3"] / 2)
ElseIf shape[i]["func"] = "line" Then
x1 = -Math.Floor(Math.Abs(shape[i]["x1"] - shape[i]["x2"]) / 2)
y1 = -Math.Floor(Math.Abs(shape[i]["y1"] - shape[i]["y2"]) / 2)
EndIf
ox = x - x1
oy = y - y1
x = x1 * Math.Cos(alpha) - y1 * Math.Sin(alpha) + ox
y = x1 * Math.Sin(alpha) + y1 * Math.Cos(alpha) + oy
EndSub
Sub SB_Workaround
' Small Basic | Workaround for Silverlight
' returns silverlight - "True" if in remote
color = GraphicsWindow.GetPixel(0, 0)
If Text.GetLength(color) > 7 Then
silverlight = "True"
msWait = 300
Else
silverlight = "False"
EndIf
EndSub
Sub Shapes_Add
' Shapes | add shapes as shapes data
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - 1 if same scale
' return shWidth, shHeight - total size of shapes
' return shAngle - current angle of shapes
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
Shapes_CalcWidthAndHeight()
s = scale
For i = iMin To iMax
GraphicsWindow.PenWidth = shape[i]["pw"] * s
If shape[i]["pw"] > 0 Then
GraphicsWindow.PenColor = shape[i]["pc"]
EndIf
If Text.IsSubText("rect|ell|tri|text", shape[i]["func"]) Then
GraphicsWindow.BrushColor = shape[i]["bc"]
EndIf
If shape[i]["func"] = "rect" Then
shape[i]["obj"] = Shapes.AddRectangle(shape[i]["width"] * s, shape[i]["height"] * s)
ElseIf shape[i]["func"] = "ell" Then
shape[i]["obj"] = Shapes.AddEllipse(shape[i]["width"] * s, shape[i]["height"] * s)
ElseIf shape[i]["func"] = "tri" Then
shape[i]["obj"] = Shapes.AddTriangle(shape[i]["x1"] * s, shape[i]["y1"] * s, shape[i]["x2"] * s, shape[i]["y2"] * s, shape[i]["x3"] * s, shape[i]["y3"] * s)
ElseIf shape[i]["func"] = "line" Then
shape[i]["obj"] = Shapes.AddLine(shape[i]["x1"] * s, shape[i]["y1"] * s, shape[i]["x2"] * s, shape[i]["y2"] * s)
ElseIf shape[i]["func"] = "text" Then
If silverlight Then
fs = Math.Floor(shape[i]["fs"] * 0.9)
Else
fs = shape[i]["fs"]
EndIf
GraphicsWindow.FontSize = fs * s
GraphicsWindow.FontName = shape[i]["fn"]
shape[i]["obj"] = Shapes.AddText(shape[i]["text"])
EndIf
x = shape[i]["x"]
y = shape[i]["y"]
shape[i]["rx"] = x
shape[i]["ry"] = y
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
alpha = Math.GetRadians(shape[i]["angle"])
SB_RotateWorkaround()
shape[i]["wx"] = x
shape[i]["wy"] = y
EndIf
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
If Text.IsSubText("rect|ell|tri|text", shape[i]["func"]) And shape[i]["angle"] <> 0 Then
Shapes.Rotate(shape[i]["obj"], shape[i]["angle"])
EndIf
EndFor
shAngle = 0
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub
Sub Shapes_CalcRotatePos
' Shapes | Calculate position for rotated shape
' param["x"], param["y"] - position of a shape
' param["width"], param["height"] - size of a shape
' param ["cx"], param["cy"] - center of rotation
' param ["angle"] - rotate angle
' return x, y - rotated position of a shape
_cx = param["x"] + param["width"] / 2
_cy = param["y"] + param["height"] / 2
x = _cx - param["cx"]
y = _cy - param["cy"]
Math_CartesianToPolar()
a = a + param["angle"]
x = r * Math.Cos(a * Math.Pi / 180)
y = r * Math.Sin(a * Math.Pi / 180)
_cx = x + param["cx"]
_cy = y + param["cy"]
x = _cx - param["width"] / 2
y = _cy - param["height"] / 2
EndSub
Sub Shapes_CalcWidthAndHeight
' Shapes | Calculate total width and height of shapes
' param iMin, iMax - shape indices to add
' return shWidth, shHeight - total size of shapes
For i = iMin To iMax
If shape[i]["func"] = "tri" Or shape[i]["func"] = "line" Then
xmin = shape[i]["x1"]
xmax = shape[i]["x1"]
ymin = shape[i]["y1"]
ymax = shape[i]["y1"]
If shape[i]["x2"] < xmin Then
xmin = shape[i]["x2"]
EndIf
If xmax < shape[i]["x2"] Then
xmax = shape[i]["x2"]
EndIf
If shape[i]["y2"] < ymin Then
ymin = shape[i]["y2"]
EndIf
If ymax < shape[i]["y2"] Then
ymax = shape[i]["y2"]
EndIf
If shape[i]["func"] = "tri" Then
If shape[i]["x3"] < xmin Then
xmin = shape[i]["x3"]
EndIf
If xmax < shape[i]["x3"] Then
xmax = shape[i]["x3"]
EndIf
If shape[i]["y3"] < ymin Then
ymin = shape[i]["y3"]
EndIf
If ymax < shape[i]["y3"] Then
ymax = shape[i]["y3"]
EndIf
EndIf
shape[i]["width"] = xmax - xmin
shape[i]["height"] = ymax - ymin
EndIf
If i = 1 Then
shWidth = shape[i]["x"] + shape[i]["width"]
shHeight = shape[i]["y"] + shape[i]["height"]
Else
If shWidth < shape[i]["x"] + shape[i]["width"] Then
shWidth = shape[i]["x"] + shape[i]["width"]
EndIf
If shHeight < shape[i]["y"] + shape[i]["height"] Then
shHeight = shape[i]["y"] + shape[i]["height"]
EndIf
EndIf
EndFor
EndSub
Sub Shapes_Move
' Shapes | Move shapes
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - to zoom
' param x, y - position to move
' return shX, shY - new position of shapes
Stack.PushValue("local", i)
s = scale
shX = x
shY = y
For i = iMin To iMax
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
_x = shape[i]["wx"]
_y = shape[i]["wy"]
Else
_x = shape[i]["rx"]
_y = shape[i]["ry"]
EndIf
Shapes.Move(shape[i]["obj"], shX + _x * s, shY + _y * s)
EndFor
i = Stack.PopValue("local")
EndSub
Sub Shapes_Remove
' Shapes | Remove shapes
' param iMin, iMax - shapes indices to remove
' param shape - array of shapes
Stack.PushValue("local", i)
For i = iMin To iMax
Shapes.Remove(shape[i]["obj"])
EndFor
i = Stack.PopValue("local")
EndSub
Sub Shapes_Rotate
' Shapes | Rotate shapes
' param iMin, iMax - shapes indices to rotate
' param shape - array of shapes
' param scale - to zoom
' param angle - to rotate
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
s = scale
param["angle"] = angle
param["cx"] = shWidth / 2
param["cy"] = shHeight / 2
For i = iMin To iMax
param["x"] = shape[i]["x"]
param["y"] = shape[i]["y"]
param["width"] = shape[i]["width"]
param["height"] = shape[i]["height"]
Shapes_CalcRotatePos()
shape[i]["rx"] = x
shape[i]["ry"] = y
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
alpha = Math.GetRadians(angle + shape[i]["angle"])
SB_RotateWorkAround()
shape[i]["wx"] = x
shape[i]["wy"] = y
EndIf
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
Shapes.Rotate(shape[i]["obj"], angle + shape[i]["angle"])
EndFor
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub
Sub FillLinearGradientRectangle
' param["x"], param["y"] - position of the rectangle
' param["width"], param["height"] - size of the rectangle
' param["angle"] - angle of gradient
' param["0"]..param["100"] - 0% to 100% colors
x0 = param["x"]
y0 = param["y"]
width = param["width"]
height = param["height"]
angle = param["angle"]
n = Array.GetItemCount(param)
index = Array.GetAllIndices(param)
color = ""
For i = 1 To n
If index[i] + 0 = index[i] And 0 <= index[i] And index[i] <= 100 Then
color[index[i]] = param[index[i]]
EndIf
EndFor
If color[0] = "" Then
color[0] = GraphicsWindow.BrushColor
EndIf
If color[100] = "" Then
color[100] = GraphicsWindow.BrushColor
EndIf
n = Array.GetItemCount(color)
index = Array.GetAllIndices(color)
a45 = Math.Remainder(angle, 45)
If 0 <= angle And angle < 45 Then
w45 = width
h45 = height
ElseIf 45 <= angle And angle < 90 Then
w45 = height
h45 = width
a45 = 45 - a45
ElseIf 90 <= angle And angle < 135 Then
w45 = height
h45 = width
ElseIf 135 <= angle And angle < 180 Then
w45 = width
h45 = height
a45 = 45 - a45
ElseIf 180 <= angle And angle < 225 Then
w45 = width
h45 = height
ElseIf 225 <= angle And angle < 270 Then
w45 = height
h45 = width
a45 = 45 - a45
ElseIf 270 <= angle And angle < 315 Then
w45 = height
h45 = width
ElseIf 315 <= angle And angle < 360 Then
w45 = width
h45 = height
a45 = 45 - a45
EndIf
If a45 = 0 Then
For x = 0 To w45
percent = Math.Floor(x * 100 / w45)
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = x
y2 = h45
DrawLine()
EndFor
ElseIf 0 < a45 And a45 <= 45 Then
tan = Math.Tan(Math.GetRadians(a45))
If h45 <= w45 Then
dx = Math.Floor(h45 * tan)
For x = 0 To dx
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = 0
y2 = Math.Floor(x / tan)
DrawLine()
EndFor
For x = dx To w45
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = x - dx
y2 = h45
DrawLine()
EndFor
For x = w45 To w45 + dx
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x - dx
y1 = h45
x2 = w45
y2 = Math.Floor((x - w45) / tan)
DrawLine()
EndFor
Else ' width < height
dx = Math.Floor(h45 * tan - w45)
dy = Math.Floor(w45 / tan)
For x = 0 To w45
percent = Math.Floor(x * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = 0
y2 = Math.Floor(x / tan)
DrawLine()
EndFor
For x = 0 To dx
percent = Math.Floor((x + w45) * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = w45
y1 = Math.Floor(x / tan)
x2 = 0
y2 = y1 + dy
DrawLine()
EndFor
dy = h45 - Math.Floor(w45 / tan)
For x = 0 To w45
percent = Math.Floor((x + w45 + dx) * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = h45
x2 = w45
y2 = dy + Math.Floor(x / tan)
DrawLine()
EndFor
EndIf
EndIf
EndSub
Sub DrawLine
' param r, g, b - red, green blue
' param angle
' param x1, y1, x2, y2 - edges of line
GraphicsWindow.PenColor = GraphicsWindow.GetColorFromRGB(r, g, b)
If 0 <= angle And angle < 45 Then
GraphicsWindow.DrawLine(x1 + x0, y1 + y0, x2 + x0, y2 + y0)
ElseIf 45 <= angle And angle < 90 Then
GraphicsWindow.DrawLine(y1 + x0, x1 + y0, y2 + x0, x2 + y0)
ElseIf 90 <= angle And angle < 135 Then
GraphicsWindow.DrawLine(-y1 + x0 + width, x1 + y0, -y2 + x0 + width, x2 + y0)
ElseIf 135 <= angle And angle < 180 Then
GraphicsWindow.DrawLine(-x1 + x0 + width, y1 + y0, -x2 + x0 + width, y2 + y0)
ElseIf 180 <= angle And angle < 225 Then
GraphicsWindow.DrawLine(-x1 + x0 + width, -y1 + y0 + height, -x2 + x0 + width, -y2 + y0 + height)
ElseIf 225 <= angle And angle < 270 Then
GraphicsWindow.DrawLine(-y1 + x0 + width, -x1 + y0 + height, -y2 + x0 + width, -x2 + y0 + height)
ElseIf 270 <= angle And angle < 315 Then
GraphicsWindow.DrawLine(y1 + x0, -x1 + y0 + height, y2 + x0, -x2 + y0 + height)
ElseIf 315 <= angle And angle < 360 Then
GraphicsWindow.DrawLine(x1 + x0, -y1 + y0 + height, x2 + x0, -y2 + y0 + height)
EndIf
EndSub
Sub Color_PercentToRGB
' Color | Convert Percent to RGB
' param percent - percent
' param color[] - color table indexed percent
' param n - item count of color[]
' param index[] - all indices of color[]
For i = 1 To n
p1 = index[i]
If index[i] = percent Then
p2 = index[i]
i = n + 1 ' break
ElseIf index[i] < percent And percent < index[i + 1] Then
p2 = index[i + 1]
i = n + 1 ' break
EndIf
EndFor
c = color[p1]
Color_ColorToRGB()
If p1 <> p2 Then
r1 = r
g1 = g
b1 = b
c = color[p2]
Color_ColorToRGB()
r2 = r
g2 = g
b2 = b
r = Math.Floor(r1 + (r2 - r1) * (percent - p1) / (p2 - p1))
g = Math.Floor(g1 + (g2 - g1) * (percent - p1) / (p2 - p1))
b = Math.Floor(b1 + (b2 - b1) * (percent - p1) / (p2 - p1))
EndIf
EndSub
Sub Color_ColorToRGB
' Color | Convert Color to RGB
' param c - color
' returns r, g, b - red, green and blue values
If Text.StartsWith(c, "#") Then
c = Text.ConvertToUpperCase(c)
Else
c = Text.ConvertToLowerCase(c)
c = colors[c]
EndIf
sHex = Text.GetSubText(c, 2, 2)
Math_Hex2Dec()
r = iDec
sHex = Text.GetSubText(c, 4, 2)
Math_Hex2Dec()
g = iDec
sHex = Text.GetSubText(c, 6, 2)
Math_Hex2Dec()
b = iDec
EndSub
Sub Math_Hex2Dec
' Math | Convert hexadecimal to decimal
' param sHex
' returns iDec
iDec = 0
iLen = Text.GetLength(sHex)
For iPtr = 1 To iLen
iDec = iDec * 16 + Text.GetIndexOf("0123456789ABCDEF", Text.GetSubText(sHex, iPtr, 1)) - 1
EndFor
EndSub