Width 80,20:Color 0,15:Cls:? ? " Created November 15, 2008 by Gabriel LaFreniere.":?:? ? " This FreeBasic program was adapted to the 0.20.0b Compiler (2008) for Windows:":? ? " http://www.freebasic.net/index.php/download":?:? ? " It should still be compatible with previous versions.":? ? " Please download the IDE (editor) from:":? ? " http://fbide.freebasic.net":?:? ' Gosub commands are not supported any more. ' All variables must be declared. ' Subs are in alphabetical order. Press F2 and double-click "Subs" ' to display the list. Then double-click the Sub name. Declare Sub Damping_Management() Declare Sub Frame_of_Reference() Declare Sub Initialization() Declare Sub Keyboard_Management() Declare Sub Mouse_Management() Declare Sub Wave_Display() Declare Sub Circular_Generator_Doppler() Const pi = 4 * Atn(1) Const black = Rgb(0,0,0), white = Rgb(255,255,255), purple = Rgb(255,0,255), dark_gray = Rgb(75,75,75) Const red = Rgb(255,0,0), blue = Rgb(0,0,255), cyan = Rgb(0,200,200), gray = Rgb(150,150,150) Const gold = Rgb(180,150,100), buff = Rgb(255,255,200), blue_sky = Rgb(210,230,255) Const green_text = Rgb(0,125,0), background = Rgb(225,225,225), green = Rgb(0,200,0) Dim Shared As Integer x_screen = 1024, y_screen = 768, x_width = 400, y_height = 400 Dim Shared As Integer x_start, y_start, x_stop, y_stop, x_center, y_center, x_mouse, y_mouse Dim Shared As Integer r, g, b, x, y, x_scanner, x_previous, x_coord, y_coord, x_squared Dim Shared As Integer r_previous(y_height), g_previous(y_height), b_previous(y_height) Dim Shared As Integer x1_emitter, x2_emitter, y_emitter, x_straight_emitter Dim Shared As Integer y_parabola, y_beam_splitter, x_vertical_mirror, x_scale Dim Shared As Integer matrix_page, work_page, visible_page, luminance_1, luminance_2, click, wheel, bitmap Dim Shared As Integer iteration, pulses, stop_pulsating, lambda, target, damping_zone = 401, parabola_radius Dim Shared As Integer frame, skipped_frames, line_number, axial, OK, unit, scan(-2 To x_width, y_height) Dim Shared As Single t_time, t_prime, k_Dewavrin, ratio, move_frame, frame_speed Dim Shared As Single orthogonal, diagonal, influence, potential, kinetic, Lagrangian, factor, previous Dim Shared As Single amplitude, phase, previous_phase, distance, radian, wave_speed, brightness, decimal Dim Shared As Single energy(x_screen, y_screen), quadrature(x_screen, y_screen), beta, mirror_angle, g_Lorentz, c_speed Dim Shared As Single damping(-damping_zone To x_screen + damping_zone, -damping_zone To y_screen + damping_zone) Dim Shared As Single past( -damping_zone To x_screen + damping_zone, -damping_zone To y_screen + damping_zone) Dim Shared As Single present(-damping_zone To x_screen + damping_zone, -damping_zone To y_screen + damping_zone) Dim Shared As Single trend( -damping_zone To x_screen + damping_zone, -damping_zone To y_screen + damping_zone) Dim Shared As String line13, line14, line15, line16, line17, line18, line19, line20 Dim Shared As String line21a, line21b, line22a, line22b, line23, line24, line25, line26, line27, line28, line29 Dim Shared As String line30, line31, line32, line33, line34, line35, line36, line37, line38, line39 Dim Shared As String line40, line41, line42, line43, line44, line45, line46, line47, line48 Dim Shared As String in_key, display, file, bitmap_number visible_page = 0: work_page = 1: matrix_page = 2: bitmap = 0 'set bitmap = 1 for BMP image sequence. Initialization() '********************************************************************* ' MAIN LOOP. '********************************************************************* Do For frame = 0 To skipped_frames ' JOCELYN MARCOTTE'S 2-D WAVE ALGORITHM (CREATED IN 2006). "THE PAST IS A GUIDE TO THE FUTURE" For x = x_start To x_stop: For y = y_start To y_stop past(x,y) = present(x,y) 'updating previous states. present(x,y) = trend(x,y) Next: Next For x = x_start To x_stop: For y = y_start To y_stop orthogonal = present(x-1, y) + present(x, y-1) + present(x, y+1) + present(x+1, y)'orthogonal influence. ' trend(x,y) = .5 * orthogonal - past(x,y) 'fastest trend extrapolation (constant pixel sum = 1). ' trend(x,y) = .4 * (orthogonal + present(x,y)) - past(x,y) 'slower wave speed: .4 * (4 + 1) - 1 = 1 trend(x,y) = .25 * (2 - wave_speed) * orthogonal + wave_speed * present(x,y) - past(x,y)'slower wave speed. Next: Next If iteration Mod lambda / 4 = 0 Then For x = 0 To x_width: For y = 0 To y_height energy(x,y) = quadrature(x,y) Next: Next For x = 0 To x_width: For y = 0 To y_height quadrature(x,y) = trend(x,y) Next: Next For x = 0 To x_width: For y = 0 To y_height energy(x,y) = Sqr(quadrature(x,y)^2 + energy(x,y)^2) Next: Next End If x_scanner -= 1 If x_scanner < -2 Then x_scanner = -2 move_frame += c_speed * frame_speed If move_frame > 1 Then move_frame -= 1: Frame_of_Reference(): OK = 1 Else OK = 0 End If ' Parabolic_Reflector() ' Flat_Mirrors() Damping_Management() 'processing damping zone. Circular_Generator_Doppler() 'circular impulses. iteration += 1 in_key = Inkey 'keyboard management. Getmouse x_mouse, y_mouse, wheel, click 'mouse management. If Len(in_key) Or click > 0 Then Exit For 'execute now. Next Wave_Display() 'skip other frames. If y_mouse < 400 Or y_mouse > 768 Or x_mouse < 360 Or x_mouse > 664 Then line_number = 0 Else line_number = .5 + y_mouse / 16 'line number in text units. End If ' If line_number = 0 And Abs(y_mouse - y_center) < 50 Then Drag_Emitters()'move emitters. If Len(in_key) Then Keyboard_Management() If line_number > 1 Or click = 2 Then Mouse_Management() If bitmap > 0 And OK = 1 And x_scanner < x_width + 100 Then 'set bitmap = 1 for bitmap sequence. Select Case bitmap Case Is < 10: bitmap_number = "00" Case Is < 100: bitmap_number = "0" Case Is < 1000: bitmap_number = "" End Select file = "capture" + bitmap_number + Str(bitmap) + ".bmp" Color red, background: Locate 44, 110: Print file Bsave file, 0 bitmap += 1 If bitmap > 999 Then End End If Loop '*********************************************************************************************************************** ' END OF MAIN LOOP. '*********************************************************************************************************************** ' SUB PROCEDURES BELOW ARE IN ALPHABETICAL ORDER (Press F2 and double-click "Subs"). '*********************************************************************************************************************** '********************************************************************* ' DAMPING ZONE AND OTHER REFLECTION OR ANTI-REFLECTION DEVICES. '********************************************************************* Sub Damping_Management() For x = x_start To 0 'progressive damping, left side. For y = y_start To y_stop trend(x,y) = damping(x,y) * trend(x,y) present(x,y) = damping(x,y) * present(x,y) Next Next For x = x_width To x_stop 'right side. For y = y_start To y_stop trend(x,y) = damping(x,y) * trend(x,y) present(x,y) = damping(x,y) * present(x,y) Next Next For x = 0 To x_width For y = y_start To 0 'upper side. trend(x,y) = damping(x,y) * trend(x,y) present(x,y) = damping(x,y) * present(x,y) Next For y = y_height To y_stop 'lower side. trend(x,y) = damping(x,y) * trend(x,y) present(x,y) = damping(x,y) * present(x,y) Next Next End Sub '********************************************************************* ' MOVING FRAME OF REFERENCE. '********************************************************************* Sub Frame_of_Reference() x1_emitter += 1 x2_emitter += 1 For x = x_stop To x_start Step -1 'moving all medium "granules" 1 pixel rightward. For y = y_start To y_stop present(x,y) = present(x-1,y) trend(x,y) = trend(x-1,y) Next Next End Sub '********************************************************************* ' INITIALIZATION. '********************************************************************* Sub Initialization() Screen 20,24,3 Windowtitle " The Time Scanner - Nov. 16, 2009" Screenset matrix_page, matrix_page Color black, background: Cls: Locate 35 lambda = 32 brightness = .7 beta = .5 g_Lorentz = Sqr(1 - beta ^ 2) pulses = 20 skipped_frames = 0 'select 0 for smoother but slower display. x_scale = -240 frame_speed = (1 - g_Lorentz) / beta 'on condition that c = 1. wave_speed = 2 / 3 'set wave_speed = 0 for fastest c_speed (minimum 1.99). c_speed = sqr((1 - beta) / (1 + beta)) 'fastest c_speed is Sin(pi / 4) = .707 pixel per loop. ' Locate 10, 10: Print c_speed/beta - c_speed*frame_speed: Sleep: End ' = 1 in order to match the scan speed = 1 pixel per loop. ' Locate 11, 10: Print wave_speed, c_speed: Sleep: End x1_emitter = .5 * x_width + 24 x2_emitter = .667 * x_width y_emitter = .5 * y_height mirror_angle = Atn(g_Lorentz / 1) x_center = .5 * x_width y_center = .5 * y_height damping_zone = 30 * Sqr(lambda) '100 for lambda = 25 to 200 for lambda = 100. iteration = 0 x_start = -damping_zone y_start = -damping_zone x_stop = x_width + damping_zone y_stop = y_height + damping_zone x_scanner = x_width + 200 If stop_pulsating = 2 Then stop_pulsating = 0 'restart. For x = x_start To x_stop 'erasing previous data. For y = y_start To y_stop past(x,y) = 0 present(x,y) = 0 trend(x,y) = 0 Next Next '********************************************************************* ' Progressive damping ratio precalculus. For x = x_start To 0 'left side damping ratio. ratio = ((damping_zone + x) / damping_zone) ^ (1/lambda) For y = y_start To y_stop damping(x,y) = ratio Next Next For x = x_width To x_stop 'right side. ratio = ((x_stop - x) / damping_zone) ^ (1/lambda) For y = y_start To y_stop damping(x,y) = ratio Next Next For x = x_start To x_stop 'upper side. For y = y_start To 0 ratio = ((damping_zone + y) / damping_zone) ^ (1/lambda) If x < 0 Then 'upper left corner. If x > y Then damping(x,y) = ratio End If Elseif x > x_width Then 'upper right corner. If x_stop - x > y - y_start Then damping(x,y) = ratio End If Else 'remaining central upper side. damping(x,y) = ratio End If Next Next For x = x_start To x_stop 'lower side. For y = y_height To y_stop ratio = ((y_stop - y) / damping_zone) ^ (1/lambda) If x < 0 Then 'lower left corner. If x + damping_zone > y_stop - y Then damping(x,y) = ratio End If Elseif x > x_width Then 'lower right corner. If x_stop - x > y_stop - y Then damping(x,y) = ratio End If Else 'remaining central lower side. damping(x,y) = ratio End If Next Next '********************************************************************* ' Display. Locate 36 ' Locate, 47: ? "Place the mouse cursor here or" ' Locate, 47: ? "press [ M ] to display the menu.":? ' Locate, 47: ? "Select wavelength here "; lambda:? Color dark_gray Locate 47, 3: ? "Thanks to the creators of FreeBASIC." Locate 48, 3: ? "Gabriel LaFreniere glafreniere.com"; Locate 47,89: ? "November 16, 2009. This program may be" Locate 48,89: ? "freely distributed, copied or modified."; Color green_text line13 = " Please Click Slowly! " line14 = " " line15 = " A- Show wave amplitude. " line16 = " B- Show wave energy. " line17 = " C- Show standing waves. " line18 = " D- " line19 = " E- Reverse wave direction. " line20 = " F- Force Standing Waves. " line21a =" G- Skip 7 Frames (Faster). " line21b =" G- Show All Frames (Slower). " line22a =" H- Show Axial Graphics. " line22b =" H- Hide Axial Graphics. " line23 = " I- Initialize. " line24 = " J- " line25 = " K- " line26 = " L- " line27 = " M- Press M to display this menu. " line28 = " N- " line29 = " O- " line30 = " P- Pause. " line31 = " Q- " line32 = " R- " line33 = " S- Stop pulsating. " line34 = " T- Constant Pulse. " line35 = " U- " line36 = " V- " line37 = " W- " line38 = " X- " line39 = " Y- " line40 = " Z- " line41 = " " line42 = " " line43 = " Pulses " line44 = " Lambda (Wavelength) " line45 = " Brightness Press [ + - = ] " line46 = " " line47 = " I- Initialize. " line48 = " Press Esc. to Quit. " Locate 47, 46: ? line47 Locate 48, 46: ? line48; Locate 47, 72: ? "P- Pause." ' Locate 48, 72: ? "R- Restart."; End Sub '********************************************************************* ' KEYBOARD MANAGEMENT. ' **** IMPORTANT **** ' Most of keybord commands are redirected to Mouse_Management Sub in ' order to simplify procedures and avoid occasional discrepancies. '********************************************************************* Sub Keyboard_Management() If Len(in_key) = 2 Then in_key = Right(in_key, 1) + "+" Else in_key = Ucase(in_key) ' Screenset work_page, work_page ' cls: locate 10, 10: print in_key: sleep 1000 'check Inkey value such as arrows, page up, etc. Select Case in_key Case Chr(27), "k+": End 'end program - escape key or Windows' X button. Case "A": line_number = 15: click = 1 'show amplitude - execute via mouse management. Case "I": Initialization() Case "P": line_number = 30: click = 1 'pause. Screenset work_page, work_page: Color red, background Locate 47, 46: ? " Paused. Press any key to resume. " Sleep: in_key = "" Case "+": brightness = brightness / Sqr(.5) 'brighter. If brightness > 4 Then brightness = 4 Case "-": brightness = brightness * Sqr(.5) 'darker. If brightness < .25 Then brightness = .25 Case "=": brightness = 1 'normal brightness. End Select in_key = "" Do: Loop While Len(Inkey) 'clear buffer. End Sub '********************************************************************* ' MOUSE MANAGEMENT. '********************************************************************* Sub Mouse_Management() Screenset work_page Color green_text, background ' Locate 44, 46: ? line44;: Locate, 66: Print lambda; " pixels." ' Line(512 - 153, 186)-(512 + 152, 191), background, bf ' Line(512 - 153, 410)-(512 + 152, 769), black, b Color green_text, white Locate line_number, 46 '********************************************************************* ' BEGIN MOUSE CLICK PROCESSING. Select Case line_number Case 47 'initialization (line 23 or 47). ? line23 If click > 0 Then Initialization() End If Case 48 'ending program. ? line48; If click > 0 Then End End Select If click = 1 Then 'avoid repetitive actions. Do: Getmouse x_mouse, y_mouse, wheel, click: Loop While click = 1 End If End Sub '********************************************************************* ' DISPLAYING POSITIVE AMPLITUDE IN GREEN AND NEGATIVE IN RED. '********************************************************************* Sub Wave_Display() ' If line_number = 1 Then Return 'show background (hide waves). Swap work_page, visible_page Screenset work_page, visible_page Pcopy matrix_page, work_page Line(66, 16)-(66 + 10 * lambda, 16), white 'stationary scale. Line(66 + 10 * lambda, 16)-(66 + 10 * lambda, 24), white Line(66 + 8.66 * lambda, 16)-(66 + 8.66 * lambda, 38), white Line(x1_emitter + x_scale, 27)-(10 * lambda + x1_emitter + x_scale, 34), white, b 'moving scale. For x = 0 To 9 * lambda Step 2 * lambda Line(x + 66, 16)-(x + 66, 24), white 'stationary scale. Line(x + 66 + lambda, 16)-(x + 66 + lambda, 24), white Line(x + x1_emitter + x_scale, 28)-(x + x1_emitter + x_scale + lambda, 33), white, bf 'moving scale. Next Circle(x1_emitter + x_scale, 73), 32, white 'moving clocks. Paint (x1_emitter + x_scale + 24, 73), white, white Circle(x1_emitter + x_scale, 73), 4, black Paint (x1_emitter + x_scale + 3, 73), black, black Circle(x1_emitter + x_scale + 10 * lambda, 73), 32, white Paint (x1_emitter + x_scale + 10 * lambda, 73), white, white Circle(x1_emitter + x_scale + 10 * lambda, 73), 4, black Paint(x1_emitter + x_scale + 10 * lambda+3, 73), black, black For t_time = - pi / 2 To 2 * pi - pi / 2 Step 2 * pi / 10 '10 clock marks. x = 29 * Cos(t_time) + x1_emitter + x_scale y = 29 * Sin(t_time) + 73 Circle(x, y), 2, black Paint(x + 1, y), black, black Circle(x + 10 * lambda, y), 2, black Paint(x + 1 + 10 * lambda, y), black, black Next Line(x1_emitter, y_emitter - 3 * lambda)-(x1_emitter, y_emitter + 3 * lambda), white For y = 0 to 3 * lambda step lambda 'vertical wavelength scale. Line(x1_emitter - 4, y_emitter + y)-(x1_emitter + 4, y_emitter + y), white Line(x1_emitter - 4, y_emitter - y)-(x1_emitter + 4, y_emitter - y), white Next Line(x1_emitter - c_speed * iteration + lambda - 4, y_emitter - 3)-(x1_emitter - c_speed * iteration + lambda - 4, y_emitter + 3), white t_time = c_speed * iteration * 2 * pi / lambda / 10 - pi / 2 - 6.05 'rotating the clock needle. x = 24 * Cos(t_time) + x1_emitter + x_scale y = 24 * Sin(t_time) + 73 Line(x1_emitter + x_scale + 10 * lambda, 73)-(x + 10 * lambda, y), black Line(x1_emitter + x_scale + 10 * lambda+1, 73)-(x + 10 * lambda+1, y), black Line(x1_emitter + x_scale + 10 * lambda-1, 73)-(x + 10 * lambda-1, y), black Line(x1_emitter + x_scale + 10 * lambda, 73 + 1)-(x + 10 * lambda, y + 1), black Line(x1_emitter + x_scale + 10 * lambda, 73 - 1)-(x + 10 * lambda, y - 1), black Line(x1_emitter + x_scale, 73)-(x, y), black Line(x1_emitter + x_scale+1, 73)-(x+1, y), black Line(x1_emitter + x_scale-1, 73)-(x-1, y), black Line(x1_emitter + x_scale, 73 + 1)-(x, y + 1), black Line(x1_emitter + x_scale, 73 - 1)-(x, y - 1), black Color white, black Locate 1, 1: ? " x = 0 1 2 3 4 5 6 7 8 9 10" Locate 4, 16: ? "The Time Scanner" Locate 16, 1: ? " t = 0 for A and B." Locate 17, 1: ? " t'= 0 for A." Locate 18, 1: ? " x = x' = 0 for A." Locate 19, 1: ? " x = 10 for B." Locate 21, 1: ? " x'= g * x + b * t = 8.66 light seconds for B." Locate 22, 1: ? " t'= g * t - b * x = -5 seconds for B." Locate 24, 1: ? " glafreniere.com beta (b) = v / c = 0.5" Locate 25, 1: ? " Contraction factor: g = Sqr(1 - b) = 0.866"; Locate 1,1: ? "AB" For x = 0 to 7: For y = 0 to 15 If Point(x,y) = -1 then pset(x + x1_emitter + x_scale - 3, y + 110), white If Point(x+8,y) = -1 then pset(x + x1_emitter + x_scale - 3 + 10 * lambda, y + 110), white Next:Next Locate 1,1: ? " " For x = 0 To x_width: For y = 0 To y_height luminance_1 = brightness * Abs(20 * trend(x,y)) b = luminance_1 / 2 If b > 255 Then b = 255 If luminance_1 > 255 Then luminance_2 = luminance_1 - 255 If luminance_2 > 255 Then luminance_2 = 255 luminance_1 = 255 Else luminance_2 = 0 End If If present(x,y) > 0 Then 'complementary magenta and emerald green. r = luminance_2 g = luminance_1 Else r = luminance_1 g = luminance_2 End If If x <= x_scanner And Point(x,y) < -1 Then Pset(x,y), Rgb(r,g,b) 'printing wave area. If x = x_scanner Then 'scanning one row at a time. r = (r_previous(y) * move_frame) + (r * (1 - move_frame)) g = (g_previous(y) * move_frame) + (g * (1 - move_frame)) b = (b_previous(y) * move_frame) + (b * (1 - move_frame)) If Point(x,y) < -1 Then scan(x,y) = Rgb(r,g,b) Else scan(x,y) = Point(x,y) Elseif x = x_scanner Then 'scanning one row at a time. End If r_previous(y) = r g_previous(y) = g b_previous(y) = b Next: Next If x_scanner <= x_width Then For x = x_scanner To x_width: For y = 0 To y_height 'printing scanned area. Pset(x,y), scan(x,y) Next: Next End If If x_scanner > 0 Then Line(x_scanner, 0)-(x_scanner, y_height), white End Sub '********************************************************************* ' CIRCULAR WAVE GENERATOR - SINUSOIDAL IMPULSE. '********************************************************************* Sub Circular_Generator_Doppler() If stop_pulsating = 2 Then Exit Sub 'no pulsation. t_time = c_speed * iteration * 2 * pi / lambda 'Lorentz's c = 1; wave speed is .6 pixel per cycle. amplitude = 1500 / lambda ^ 2 If stop_pulsating = 0 Then If iteration > 2 * (pulses - 2) * lambda / g_Lorentz Then 'wave speed is .5 pixel per cycle. stop_pulsating = 1 'prepare for stopping during last pulse. t_prime = g_Lorentz * t_time 'Lorentz's inverted: t' = g * t (slower pulses). previous_phase = Cos(t_prime) target = iteration + 2 * lambda End If Elseif stop_pulsating = 1 Then 'stop pulsating when amplitude reaches a minimum. t_prime = g_Lorentz * t_time previous_phase = Cos(t_prime) End If If iteration < 4 * lambda Then 'start pulsating gradually. amplitude = amplitude * iteration / (4 * lambda) 'useful for beam splitter, may be omitted. End If If stop_pulsating = 1 Then 'stop pulsating gradually. amplitude = amplitude * (target - iteration) / (2 * lambda) 'useful for beam splitter, may be omitted. If amplitude < 0 Then stop_pulsating = 2: Exit Sub End If For x = -lambda / 4 To lambda / 4 'stationary emitter. x_squared = x ^ 2 potential = amplitude * Cos(t_time) For y = -lambda / 4 To lambda / 4 distance = Sqr(x_squared + y^2) If distance < lambda / 4 Then radian = 2 * pi * distance / lambda trend(x1_emitter + x, y_emitter + y) = trend(x1_emitter + x, y_emitter + y) + potential * Cos(radian) End If Next Next ' For x = -(g_Lorentz * lambda) / 4 To (g_Lorentz * lambda) / 4 'moving emitter. ' x_squared = ((x + frame_speed) / g_Lorentz) ^ 2 ' t_prime = g_Lorentz * t_time - beta * ((x + frame_speed) / lambda) 'Lorentz's inverted: t' = g * t - beta * x ' potential = amplitude * Cos(t_prime) ' For y = -lambda / 4 To lambda / 4 ' distance = Sqr(x_squared + y^2) ' If distance < lambda / 4 Then ' radian = 2 * pi * distance / lambda ' trend(x2_emitter+x,y_emitter+y)=trend(x2_emitter+x,y_emitter+y) + potential * Cos(radian) ' End If ' Next ' Next End Sub