Web Version of WaveInterference
Smart Pascal version of WaveInterference by James Gunn
Introduction
Click on the green up arrow at the foot of the page to see the original program. If the program does not work in your current browser, try another such as Chrome. If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page. The Smart Pascal code of the form unit and the XML code of the form follow.
Program in Action
Code of Unit Form1
unit Form1; { Copyright (c) 2011 James Gunn Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ Converted to Smart Pascal for web preview by PPS 2014 } interface uses SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.PaintBox, SmartCL.Controls.EditBox, SmartCL.Controls.Label, SmartCL.Controls.CheckBox, SmartCL.Controls.Button, SmartCL.Controls.Listbox, System.Colors; type TForm1 = class(TW3Form) procedure btnViewClick(Sender: TObject); private {$I 'Form1:intf'} inputs : array[0..11] of TW3EditBox; amp : array of integer; offset, freq : array of float; colour : array of integer; num_waves, sumN, sumF : integer; RANDOM_WAVE : boolean = false; protected procedure InitializeForm; override; procedure InitializeObject; override; procedure SetUpEditBoxes; procedure ShowEditBoxes; procedure ReadEditBoxes; end; implementation procedure TForm1.SetUpEditBoxes; begin for var i := 0 to 11 do begin inputs[i] := new TW3EditBox(self); inputs[i].Width := 40; inputs[i].Height := 32; inputs[i].Left := 300 + (i div 3) * 48; inputs[i].Top := 32 *(i mod 3); inputs[i].text := ''; inputs[i].visible := true; end; end; procedure TForm1.ShowEditBoxes; begin for var i := 0 to 11 do if i < num_waves * 3 then inputs[i].visible := true else inputs[i].visible := false; end; procedure TForm1.ReadEditBoxes; begin for var i := 0 to num_waves * 3 - 1 do case i mod 3 of 0 : amp[i div 3] := strToint(inputs[i].text); 1 : offset[i div 3] := strTofloat(inputs[i].text) * pi / 180; 2 : freq[i div 3] := strTofloat(inputs[i].text); end; end; procedure TForm1.btnViewClick(Sender: TObject); begin pb.Canvas.FillStyle := 'lightblue'; pb.Canvas.FillRect(0, 0, pb.Width, pb.Height); //Extend the arrays to fit the number of waves the user has specified amp.SetLength(num_waves); offset.SetLength(num_waves); colour.SetLength(num_waves); freq.SetLength(num_waves); RANDOM_WAVE := chkRandom.Checked; // Generate a random amplitude for the wave between 25 and 50 if we are // running in random wave mode. for var i := 0 to num_waves - 1 do begin colour[i] := (randomInt(155) + 100) + (randomInt(155) + 100) * 256 + (randomInt(200) + 55) * 256 * 256; if RANDOM_WAVE then begin amp[i] := randomInt(50) + 25; freq[i] := (randomInt(50) / 10) + 1; offset[i] := randomInt(360) * pi / 180; end end; if not RANDOM_WAVE then ReadEditBoxes; //Draw the axis. pb.Canvas.beginPath; pb.Canvas.StrokeStyle := 'white'; pb.Canvas.MoveToF(1, pb.Height div 2); pb.Canvas.LineToF(pb.Width, pb.Height div 2); pb.Canvas.Stroke; for var i := 0 to pb.Width do begin //Loop through all of the waves that have been set up (could be random or user defined). for var j := 0 to num_waves - 1 do begin pb.Canvas.beginPath; //Set the colour to draw the wave as the colour generated above. pb.Canvas.StrokeStyle := ColorToWebStr(colour[j]); //Calculate the y-value of the wave at the current x-value (i) based on the //amplitude, frequency and offset. pb.Canvas.MoveToF(i, Round(Sin(((i * pi / 180) * freq[j]) + offset[j]) * amp[j]) + pb.Height div 2); //Calculate the y-value for the next x-value and draws the line between //them, thereby drawing the first section of the wave. pb.Canvas.LineToF(i + 1, Round(Sin((((i + 1) * pi / 180) * freq[j]) + offset[j]) * amp[j]) + pb.Height div 2); pb.Canvas.Stroke; end; end; pb.Canvas.StrokeStyle := 'white'; pb.Canvas.beginpath; for var i:= 0 to pb.Width do begin sumN := 0; sumF := 0; //Add up the y-value of all waves at the current x-value. for var j := 0 to num_waves - 1 do sumN := sumN + Round(Sin((( i * pi / 180) * freq[j]) + offset[j]) * amp[j]); //Add up the y-value of all waves at the next x-value. for var j := 0 to num_waves-1 do sumF := sumF + Round(Sin((((i + 1) * pi / 180) * freq[j]) + offset[j]) * amp[j]); pb.Canvas.MoveToF(1, pb.Height div 2); pb.Canvas.LineToF(pb.Width, pb.Height div 2); //The sum is only drawn if there are 2 or more waves. if num_waves > 1 then begin //Using the sums calculated above, draw each section of the sum wave. pb.Canvas.MoveToF(i, sumN + pb.Height div 2); pb.Canvas.LineToF(i + 1, sumF + pb.Height div 2); end; pb.Canvas.Stroke; end; end; procedure TForm1.InitializeForm; begin inherited; SetUpEditBoxes; ShowEditBoxes; end; procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} Randomize; num_waves := 2; W3ListBox1.ItemClass := TW3Label; W3ListBox1.Add; W3ListBox1.Add; W3ListBox1.Add; W3ListBox1.Styles.SelectedColor := clLightBlue; W3ListBox1.SelectedIndex := 0; W3ListBox1.ItemHeight := 20; W3ListBox1.SetSize(30, 75); W3ListBox1.EnableAnimation := false; W3ListBox1.OnSelected := procedure (sender: TObject; idx: integer) begin num_waves := idx + 2; ShowEditBoxes; end; TW3Label(W3ListBox1.Items[0]).Caption:= '2'; TW3Label(W3ListBox1.Items[1]).Caption:= '3'; TW3Label(W3ListBox1.Items[2]).Caption:= '4'; end; initialization Forms.RegisterForm({$I %FILE%}, TForm1); end.
XML Code of Form
<SMART> <Form version="2" subversion="1"> <Created>2014-10-15T18:34:53.620</Created> <Modified>2014-10-18T17:29:25.401</Modified> <object type="TW3Form"> <Caption>W3Form</Caption> <Name>Form1</Name> <object type="TW3PaintBox"> <Width>750</Width> <Top>104</Top> <Height>600</Height> <Name>pb</Name> </object> <object type="TW3Label"> <Caption>Waves Per Run</Caption> <Width>128</Width> <Height>32</Height> <Name>W3Label1</Name> </object> <object type="TW3Label"> <Caption>Amplitudes</Caption> <Width>128</Width> <Left>128</Left> <Height>32</Height> <Name>W3Label2</Name> </object> <object type="TW3CheckBox"> <Caption>Random Waves</Caption> <Width>128</Width> <Top>8</Top> <Left>596</Left> <Height>32</Height> <Name>chkRandom</Name> </object> <object type="TW3Label"> <Caption>Offsets</Caption> <Width>56</Width> <Top>32</Top> <Left>128</Left> <Height>32</Height> <Name>W3Label3</Name> </object> <object type="TW3Label"> <Caption>Frequency Multipliers</Caption> <Width>176</Width> <Top>64</Top> <Left>128</Left> <Height>32</Height> <Name>W3Label4</Name> </object> <object type="TW3Button"> <Caption>View Waves</Caption> <Width>128</Width> <Top>36</Top> <Left>599</Left> <Height>32</Height> <Name>btnView</Name> <OnClick>btnViewClick</OnClick> </object> <object type="TW3ListBox"> <Width>40</Width> <Top>29</Top> <Left>40</Left> <Height>56</Height> <Name>W3ListBox1</Name> </object> <object type="TW3Label"> <Caption>(Sum is white)</Caption> <Width>128</Width> <Top>68</Top> <Left>612</Left> <Height>32</Height> <Name>W3Label5</Name> </object> </object> </Form> </SMART>