Microsoft Small Basic

Program Listing: MLM021
' Prism
' Copyright © 2017 Nonki Takahashi. The MIT License.
' Last update 2017-09-07

GraphicsWindow.Title = "Prism"
Init()
θ1 = 40
n1 = 1 ' refractive index of air
n2 = 1.5 ' refractive index of glass
_θ1 = Math.GetRadians(θ1)
_θ2 = Math.ArcSin(n1 / n2 * Math.Sin(_θ1))
θ2 = Math.GetDegrees(_θ2)
_xo = r
_yo = 0
xo = gw / 2 + Math.Cos(_a) * _xo - Math.Sin(_a) * _yo
yo = gh / 2 + Math.Sin(_a) * _xo + Math.Cos(_a) * _yo
x = xo + 300 * Math.Cos(_a - _θ1)
y = yo + 300 * Math.Sin(_a - _θ1)
GraphicsWindow.DrawLine(x, y, xo, yo)
l = e / (Math.Sin(_θ2) + 1 / r3 * Math.Cos(_θ2))
xo2 = xo + l * Math.Cos(_a + Math.Pi - _θ2)
yo2 = yo + l * Math.Sin(_a + Math.Pi - _θ2)
GraphicsWindow.DrawLine(xo, yo, xo2, yo2)
param = "r=30;x="+xo+";y="+yo+";a1="+(a)+";a2="+(a-θ1)+";"
DrawArc()
_a = Math.GetRadians(a - θ1 / 2)
r = 50
GraphicsWindow.FontSize = 12
x = xo + r * Math.Cos(_a) - 4
y = yo + r * Math.Sin(_a) - 6
GraphicsWindow.DrawText(x, y, "θ")
GraphicsWindow.FontSize = 9
GraphicsWindow.DrawText(x + 8, y + 6, "1")
param = "r=30;x="+xo+";y="+yo+";a1="+(a+180)+";a2="+(a+180-θ2)+";"
DrawArc()
_a = Math.GetRadians(a + 180 - θ2 / 2)
r = 50
GraphicsWindow.FontSize = 12
x = xo + r * Math.Cos(_a) - 4
y = yo + r * Math.Sin(_a) - 6
GraphicsWindow.DrawText(x, y, "θ")
GraphicsWindow.FontSize = 9
GraphicsWindow.DrawText(x + 8, y + 6, "2")
θ3 = 60 - θ2
_θ3 = Math.GetRadians(θ3)
_θ4 = Math.ArcSin(n2 / n1 * Math.Sin(_θ3))
θ4 = Math.GetDegrees(_θ4)
r = e * r3 / 3
a = 150
_a = Math.GetRadians(a)
param = ""
param["x2"] = xo2 + r * Math.Cos(_a)
param["y2"] = yo2 + r * Math.Sin(_a)
a = -30
_a = Math.GetRadians(a)
param["x1"] = xo2 + r * Math.Cos(_a)
param["y1"] = yo2 + r * Math.Sin(_a)
DrawDottedLine()
x = xo2 + 300 * Math.Cos(_a + _θ4)
y = yo2 + 300 * Math.Sin(_a + _θ4)
GraphicsWindow.DrawLine(x, y, xo2, yo2)
Dump()

Sub Dump
buf = "θ1=" + (Math.Floor(θ1 * 100) / 100) + LF
buf = buf + "θ2=" + (Math.Floor(θ2 * 100) / 100) + LF
buf = buf + "θ3=" + (Math.Floor(θ3 * 100) / 100) + LF
buf = buf + "θ4=" + (Math.Floor(θ4 * 100) / 100) + LF
GraphicsWindow.FontSize = 12
GraphicsWindow.DrawText(10, 10, buf)
EndSub

Sub Init
LF = Text.GetCharacter(10)
Not = "False=True;True=False;"
gw = 598
gh = 428
GraphicsWindow.Width = 598
GraphicsWindow.Height = 428
GraphicsWindow.BackgroundColor = "Black"
GraphicsWindow.BrushColor = "#666666"
r3 = Math.SquareRoot(3)
e = 100
x1 = gw / 2
y1 = gh / 2 - e * r3 * 2 / 3
x2 = gw / 2 - e
y2 = gh / 2 + e * r3 / 3
x3 = gw / 2 + e
y3 = y2
GraphicsWindow.FillTriangle(x1, y1, x2, y2, x3, y3)
GraphicsWindow.PenColor = "White"
GraphicsWindow.BrushColor = "White"
a = -150
_a = Math.GetRadians(a)
param = ""
r = e * r3 * 2 / 3
param["x1"] = gw / 2 + r * Math.Cos(_a)
param["y1"] = gh / 2 + r * Math.Sin(_a)
param["x2"] = gw / 2
param["y2"] = gh / 2
DrawDottedLine()
a = -150
_a = Math.GetRadians(a)
r = e * r3 / 3
_x1 = r + 10
_y1 = 0
_x2 = r + 10
_y2 = 10
x1 = gw / 2 + Math.Cos(_a) * _x1 - Math.Sin(_a) * _y1
y1 = gh / 2 + Math.Sin(_a) * _x1 + Math.Cos(_a) * _y1
x2 = gw / 2 + Math.Cos(_a) * _x2 - Math.Sin(_a) * _y2
y2 = gh / 2 + Math.Sin(_a) * _x2 + Math.Cos(_a) * _y2
GraphicsWindow.DrawLine(x1, y1, x2, y2)
_x1 = r
_y1 = 10
_x2 = r + 10
_y2 = 10
x1 = gw / 2 + Math.Cos(_a) * _x1 - Math.Sin(_a) * _y1
y1 = gh / 2 + Math.Sin(_a) * _x1 + Math.Cos(_a) * _y1
x2 = gw / 2 + Math.Cos(_a) * _x2 - Math.Sin(_a) * _y2
y2 = gh / 2 + Math.Sin(_a) * _x2 + Math.Cos(_a) * _y2
GraphicsWindow.DrawLine(x1, y1, x2, y2)
EndSub

Sub DrawArc
Stack.PushValue("local", a)
xo = param["x"]
yo = param["y"]
r = param["r"]
a1 = param["a1"]
a2 = param["a2"]
aMin = Math.Min(a1, a2)
aMax = Math.Max(a1, a2)
last = "False"
For a = aMin To aMax Step 5
_a = Math.GetRadians(a)
x = xo + r * Math.Cos(_a)
y = yo + r * Math.Sin(_a)
If aMin < a Then
GraphicsWindow.DrawLine(x, y, xLast, yLast)
EndIf
If Not[last] And (aMax < a + 5) Then
a = aMax - 5
last = "True"
EndIf
xLast = x
yLast = y
EndFor
a = Stack.PopValue("local")
EndSub

Sub DrawDottedLine
x1 = param["x1"]
y1 = param["y1"]
x2 = param["x2"]
y2 = param["y2"]
l = Math.SquareRoot(Math.Power(x2 - x1, 2) + Math.Power(y2 - y1, 2))
dl = 3
r = 1
dr = dl / l * r
i = 0
For r = 0 To 1 Step dr
x = x1 + (x2 - x1) * r
y = y1 + (y2 - y1) * r
If Math.Remainder(i, 2) = 1 Then
GraphicsWindow.DrawLine(x, y, xLast, yLast)
EndIf
xLast = x
yLast = y
i = i + 1
EndFor
EndSub