Microsoft Small Basic

Program Listing: XLZ859
' Known Issue Workaround - Wide Line Rotates Not from Center
' Copyright © Nonki Takahashi. The MIT License.
' Last update 2019-05-18

GraphicsWindow.Title = "Known Issue Workaround - Wide Line Rotates Not from Center"
Not = "True=False;False=True;"
debug = "False"
GW_DrawGrid()
x = 100
y = 80
width = 120
height = 240
pw = width
GraphicsWindow.PenWidth = pw
slant = 0 ' [degree]
_slant = Math.GetRadians(slant)
GraphicsWindow.BrushColor = "#000000"
GraphicsWindow.DrawText(10, 10, "slant = " + slant)
txt = Shapes.AddText("alpha = 0")
Shapes.Move(txt, 10, 30)
GraphicsWindow.BrushColor = "#66000000"
x1 = 0
y1 = 0
x2 = -height * Math.Sin(_slant)
y2 = height * Math.Cos(_slant)
line = Shapes.AddLine(x1, y1, x2, y2)
lx = x + width / 2 - x2 / 2
ly = y + height / 2 - y2 / 2
Shapes.Move(line, lx, ly)
GraphicsWindow.PenWidth = 0
GraphicsWindow.BrushColor = "#660099FF"
rect = Shapes.AddRectangle(width, height)
Shapes.Rotate(rect, slant)
GraphicsWindow.BrushColor = "#6600FF00"
GraphicsWindow.FillRectangle(x, y, width, height)
Shapes.Move(rect, x, y)
GraphicsWindow.KeyDown = OnKeyDown
Wait()
While "True"
For alpha = 5 To 360 Step 5
Shapes.SetText(txt, "alpha = " + alpha)
Shapes.Rotate(line, alpha)
x = lx
y = ly
SB_LineWorkaround()
Shapes.Move(line, x, y)
Shapes.Rotate(rect, slant + alpha)
If Math.Remainder(alpha, 90) = 0 Then
Wait()
Else
Program.Delay(200)
EndIf
EndFor
EndWhile

Sub OnKeyDown
keyDown = "True"
EndSub

Sub Plot
GraphicsWindow.PenColor = "Red"
GraphicsWindow.PenWidth = 2
x = lx + x2 / 2 + Δx
y = ly + y2 / 2 + Δy
l1 = Shapes.AddLine(x - 4, y - 4, x + 4, y + 4)
l2 = Shapes.AddLine(x - 4, y + 4, x + 4, y - 4)
EndSub

Sub Wait
If debug Then
Plot()
keyDown = "False"
While Not[keyDown]
Program.Delay(200)
EndWhile
Shapes.Remove(l1)
Shapes.Remove(l2)
Else
Program.Delay(1000)
EndIf
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

Sub SB_LineWorkaround
' Small Basic | line rotate workaround for Silverlight
' param x, y - coordinate of the position of the line
' param x1, y1 - coordinate of the first point
' param x2, y2 - coordinate of the second point
' param pw - pen width
' param alpha - to rotate [degree]
' return x, y - workaround value for the coordinate
Stack.PushValue("local", x)
Stack.PushValue("local", y)
x = x1 - x2
y = y1 - y2
Math_CartesianToPolar()
y = Stack.PopValue("local")
x = Stack.PopValue("local")
_a = Math.GetRadians(a)
_alpha = Math.GetRadians(a - alpha)
Δx = pw / 4 * (Math.Sin(_alpha) - Math.Sin(_a))
Δy = pw / 4 * (Math.Cos(_alpha) - Math.Cos(_a))
If Not[debug] Then
x = x - Δx
y = y - Δy
EndIf
EndSub

Sub GW_DrawGrid
' GraphicsWindow | draw grid
_gw = GraphicsWindow.Width
_gh = GraphicsWindow.Height
_c100 = "#66000000"
_c10 = "#33000000"
For _x = 0 To _gw Step 10
If Math.Remainder(_x / 10, 10) = 0 Then
GraphicsWindow.PenColor = _c100
Else
GraphicsWindow.PenColor = _c10
EndIf
GraphicsWindow.DrawLine(_x, 0, _x, _gh)
EndFor
For _y = 0 To _gh Step 10
If Math.Remainder(_y / 10, 10) = 0 Then
GraphicsWindow.PenColor = _c100
Else
GraphicsWindow.PenColor = _c10
EndIf
GraphicsWindow.DrawLine(0, _y, _gw, _y)
EndFor
EndSub