Ok, this is going to take some explaining before I present the code. The algorithm Im implementing is called
TLM [
^]for short.
To construct the algorithm I have noticed that each cell or node, can communicate with 4 of its neighbors, called North, South, West and East for conviniance. In each of the directions it can send a pressure coeficcient and recieve a pressure coefficient for the neighbors, so each node will have 8 possible connections, that works sort of independent of each other.
In addition to the connections, each node will have a pressure at each point that is just the sum of the incoming waves.
The problem Im having is that it seems that the point of the source is moving to point 0,0 from the center of the matrix, and I cant figure out why. (Looks like there is a Doppler effect going on).
The code below is rather long (appologies) but ITs a complete functioning code, except for the doppler thing. I cant figur out why I dosnt work as it should... Can anybody see my mistake?
In XAML:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Name="btnStart">Start</Button>
<Border BorderThickness="2" BorderBrush="blue" HorizontalAlignment="Center" >
<Canvas Name="cnvTLM" Background="White" Width="300" Height="300"></Canvas>
</Border>
</StackPanel>
</Window>
And the complete VB code:
Imports System.Windows.Threading
Class MainWindow
Private Dimensions As Integer = 200
Private IncommingEast(Dimensions, Dimensions), InncommingNorth(Dimensions, Dimensions), IncommingWest(Dimensions, Dimensions), IncommingSouth(Dimensions, Dimensions), ScatteredEast(Dimensions, Dimensions), ScatteredNorth(Dimensions, Dimensions), ScatteredWest(Dimensions, Dimensions), ScatteredSouth(Dimensions, Dimensions) As Double
Private CurrentPressure(Dimensions, Dimensions) As Double
Dim SimulationTimer As DispatcherTimer
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
FillInColorList()
SimulationTimer = New DispatcherTimer()
AddHandler SimulationTimer.Tick, AddressOf SimulationTimer_Tick
SimulationTimer.Interval = New TimeSpan(0, 0, 0, 0, 100)
End Sub
Dim TT As Double = 1
Private Sub SimulationTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
For x As Integer = 1 To Dimensions - 2
For y As Integer = 1 To Dimensions - 2
If x = CInt(Dimensions / 2) And y = CInt(Dimensions / 2) Then
IncommingEast(x, y) = 30 * Math.Sin(2 * Math.PI * TT / 10) + IncommingEast(x, y)
IncommingWest(x, y) = 30 * Math.Sin(2 * Math.PI * TT / 10) + IncommingWest(x, y)
IncommingSouth(x, y) = 30 * Math.Sin(2 * Math.PI * TT / 10) + IncommingSouth(x, y)
InncommingNorth(x, y) = 30 * Math.Sin(2 * Math.PI * TT / 10) + InncommingNorth(x, y)
End If
ScatteredNorth(x, y) = 0.5 * (+IncommingEast(x, y) - InncommingNorth(x, y) + IncommingWest(x, y) + IncommingSouth(x, y))
ScatteredEast(x, y) = 0.5 * (-IncommingEast(x, y) + InncommingNorth(x, y) + IncommingWest(x, y) + IncommingSouth(x, y))
ScatteredWest(x, y) = 0.5 * (+IncommingEast(x, y) + InncommingNorth(x, y) - IncommingWest(x, y) + IncommingSouth(x, y))
ScatteredSouth(x, y) = 0.5 * (+IncommingEast(x, y) + InncommingNorth(x, y) + IncommingWest(x, y) - IncommingSouth(x, y))
IncommingEast(x, y) = ScatteredWest(x + 1, y)
InncommingNorth(x, y) = ScatteredSouth(x, y + 1)
IncommingWest(x, y) = ScatteredEast(x - 1, y)
IncommingSouth(x, y) = ScatteredNorth(x, y - 1)
CurrentPressure(x, y) = (0.5 * (ScatteredEast(x, y) + ScatteredNorth(x, y) + ScatteredWest(x, y) + ScatteredSouth(x, y)))
Next
Next
TT += 1
Dim img As New ImageBrush
img.ImageSource = CreateBitmap(CurrentPressure, Dimensions, Dimensions)
cnvTLM.Background = img
CommandManager.InvalidateRequerySuggested()
End Sub
Private Sub btnStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnStart.Click
If SimulationTimer.IsEnabled Then
SimulationTimer.Stop()
Else
SimulationTimer.Start()
End If
End Sub
Private Sub FillInColorList()
Dim f As New SmoothColorGenerator
SmoothColorList = f.ColorList
End Sub
Dim SmoothColorList As New List(Of Color)
Private Function CreateBitmap(ByVal IntegerArray(,) As Double, ByVal Width As Integer, ByVal Height As Integer, Optional ByVal DistinctColorSettings As Boolean = False) As BitmapSource
Dim buffer As New List(Of Byte)
Dim ColList As List(Of Color)
If DistinctColorSettings Then
ColList = SmoothColorList
Else
ColList = SmoothColorList
End If
Dim B_MASK As Integer = 255
Dim G_MASK As Integer = 255 << 8
Dim R_MASK As Integer = 255 << 16
For x As Integer = 0 To IntegerArray.GetLength(1) - 1
For y As Integer = 0 To IntegerArray.GetLength(0) - 1
Dim k As Integer = 0
k = (IntegerArray(x, y) / 2 + 125)
B_MASK = ColList(k).B
G_MASK = ColList(k).G
R_MASK = ColList(k).R
buffer.Add(B_MASK)
buffer.Add(G_MASK)
buffer.Add(R_MASK)
buffer.Add(255)
Next
Next
Dim dpiX As Double = 96D
Dim dpiY As Double = 96D
Dim pixelFormat = PixelFormats.Pbgra32
Dim bytesPerPixel = Math.Truncate(((pixelFormat.BitsPerPixel + 7) / 8))
Dim stride = bytesPerPixel * IntegerArray.GetLength(0)
Return BitmapSource.Create(IntegerArray.GetLength(0) - 1, IntegerArray.GetLength(1) - 1, dpiX, dpiY,
pixelFormat, Nothing, buffer.ToArray, stride)
End Function
Private Function CreateBitmap(ByVal IntegerArray(,) As Integer, ByVal Width As Integer, ByVal Height As Integer, Optional ByVal DistinctColorSettings As Boolean = False) As BitmapSource
Dim buffer As New List(Of Byte)
Dim ColList As List(Of Color)
If DistinctColorSettings Then
ColList = SmoothColorList
Else
ColList = SmoothColorList
End If
For i As Integer = 0 To Width - 1
For j As Integer = 0 To Height - 1
Dim k As Integer = IntegerArray(i, j)
buffer.Add(ColList(k).R)
buffer.Add(ColList(k).G)
buffer.Add(ColList(k).B)
buffer.Add(255)
Next
Next
Dim dpiX As Double = 96D
Dim dpiY As Double = 96D
Dim pixelFormat = PixelFormats.Pbgra32
Dim bytesPerPixel = Math.Truncate(((pixelFormat.BitsPerPixel + 7) / 8))
Dim stride = bytesPerPixel * Width
Return BitmapSource.Create(Width, Height, dpiX, dpiY,
pixelFormat, Nothing, buffer.ToArray, stride)
End Function
End Class
#Region "GenerateColorListClasses"
Public Class SmoothColorGenerator
Sub New()
GradientStop.Add(Brushes.Red)
GradientStop.Add(Brushes.White)
GradientStop.Add(Brushes.Blue)
For i As Integer = 0 To GradientStop.Count - 2
GetGradients(GradientStop(i).Color, GradientStop(i + 1).Color, 125)
Next
End Sub
Private pGradientStop As New List(Of SolidColorBrush)
Public Property GradientStop() As List(Of SolidColorBrush)
Get
Return pGradientStop
End Get
Set(ByVal value As List(Of SolidColorBrush))
pGradientStop = value
End Set
End Property
Private pColorlist As New List(Of Color)
Public Property ColorList() As List(Of Color)
Get
Return pColorlist
End Get
Set(ByVal value As List(Of Color))
pColorlist = value
End Set
End Property
Public Sub GetGradients(ByVal starts As Color, ByVal ends As Color, ByVal steps As Integer)
Dim stepA As Integer = Math.Truncate((CInt(ends.A) - CInt(starts.A)) / (CInt(steps) - 1))
Dim stepR As Integer = Math.Truncate((CInt(ends.R) - CInt(starts.R)) / (CInt(steps) - 1))
Dim stepG As Integer = Math.Truncate((CInt(ends.G) - CInt(starts.G)) / (CInt(steps) - 1))
Dim stepB As Integer = Math.Truncate((CInt(ends.B) - CInt(starts.B)) / (CInt(steps) - 1))
For i As Integer = 0 To steps - 1
ColorList.Add(Color.FromArgb(CInt(starts.A) + CInt(stepA) * CInt(i),
CInt(starts.R) + CInt(stepR) * CInt(i),
CInt(starts.G) + CInt(stepG) * CInt(i),
CInt(starts.B) + CInt(stepB) * CInt(i)))
Next
End Sub
End Class
#End Region