Bouncing Light Beam Off Mirror
Code: (Select All)
Option _Explicit
_Title "Bounce Light Beam" ' b+ 2022-10-18
Screen _NewImage(800, 600, 32) ' standard screen size 800 wide, 600 height for quick QB64 Demos with full color potential (the 32)
_ScreenMove 250, 50
Randomize Timer
Dim As Long cx, cy, mirrorRadius, Legend, mirrorDegrees, mx, my, degreeAngleMouse, diff
Dim mirrorx1, mirrory1, mirrorx2, mirrory2, distMouse, normal
cx = 400: cy = 300: mirrorRadius = _Hypot(400, 300) ' <<< long enough to span screen at any angle
Cls ' <<<<<<< this gives us a solid black background in our image of legend we are going to make
Print " Mouse is source of beam pointed to center of screen, rotate mirror with mouse wheel."
Print " Silver = mirror reflecting light beam"
Print " Yellow = the angle of beam to center point of screen"
Print " Blue = the line perpendicular to mirror"
Print " Green = angle of refelection off mirror at the center point"
Legend = _NewImage(_Width, _Height, 32) ' make copy of screen note
_PutImage , 0, Legend
Do
_PutImage , Legend, 0 ' because of black background this effectively erases image from loop before no CLS needed
While _MouseInput ' get mouse wheel changes and update status of mouse
If mirrorDegrees + _MouseWheel * 5 <= 90 And mirrorDegrees + _MouseWheel * 5 >= 0 Then mirrorDegrees = mirrorDegrees + _MouseWheel * 5
Wend
mx = _MouseX: my = _MouseY
' draw the mirror = silver
mirrorx1 = cx + mirrorRadius * CosD(mirrorDegrees)
mirrory1 = cy + mirrorRadius * SinD(mirrorDegrees)
mirrorx2 = cx + mirrorRadius * CosD(mirrorDegrees + 180)
mirrory2 = cy + mirrorRadius * SinD(mirrorDegrees + 180)
Line (mirrorx1, mirrory1)-(mirrorx2, mirrory2), _RGB32(200)
' perpendicular to mirror, both sides = blue
normal = mirrorDegrees + 90
ArrowTo cx, cy, normal, 100, _RGB32(0, 0, 255)
ArrowTo cx, cy, normal + 180, 100, _RGB32(0, 0, 255)
' light beam from mouse source to cx, cy = yellow
degreeAngleMouse = DAtan2(mx, my, cx, cy)
distMouse = _Hypot(cx - mx, cy - my)
ArrowTo mx, my, degreeAngleMouse, distMouse, _RGB32(255, 255, 0)
' diff = angle of mouse to normal but flipped 180 because reflected back
diff = normal - DAtan2(cx, cy, mx, my)
ArrowTo cx, cy, normal + diff, distMouse, _RGB32(0, 200, 0)
_Display
_Limit 60
Loop Until _KeyDown(27) ' we are done when escape is pressed
' use angles in degrees units instead of radians (converted inside sub)
Function CosD (degrees)
' Note this function uses whatever the default type is, better not be some Integer Type.
CosD = Cos(_D2R(degrees))
End Function
' use angles in degrees units instead of radians (converted inside sub)
Function SinD (degrees)
' Note this function uses whatever the default type is, better not be some Integer Type.
SinD = Sin(_D2R(degrees))
End Function
' use angles in degrees units instead of radians (converted inside sub)
Function DAtan2 (x1, y1, x2, y2) ' The angle in degrees a 2nd point (x2, y2) makes to a first point (x1, y1)
' Note this function uses whatever the default type is, better not be some Integer Type.
' Delta means change between 1 measure and another for example x2 - x1
Dim deltaX, deltaY, rtn
deltaX = x2 - x1
deltaY = y2 - y1
' To find the angle point(x2, y2) makes to (x1, y1) in Degrees
' Take DegreeAngle = DAtan2(y2 - y1, x2 - x1)
rtn = _R2D(_Atan2(deltaY, deltaX))
If rtn < 0 Then DAtan2 = rtn + 360 Else DAtan2 = rtn
End Function
' use angles in degrees units instead of radians (converted inside sub)
Sub ArrowTo (BaseX As Long, BaseY As Long, dAngle As Double, lngth As Long, colr As _Unsigned Long)
Dim As Long x1, y1, x2, y2, x3, y3
Dim As Double rAngle
rAngle = _D2R(dAngle)
x1 = BaseX + lngth * Cos(rAngle)
y1 = BaseY + lngth * Sin(rAngle)
x2 = BaseX + .8 * lngth * Cos(rAngle - _Pi(.05))
y2 = BaseY + .8 * lngth * Sin(rAngle - _Pi(.05))
x3 = BaseX + .8 * lngth * Cos(rAngle + _Pi(.05))
y3 = BaseY + .8 * lngth * Sin(rAngle + _Pi(.05))
Line (BaseX, BaseY)-(x1, y1), colr
Line (x1, y1)-(x2, y2), colr
Line (x1, y1)-(x3, y3), colr
End Sub
b = b + ...