Here is a little help on getting you started with this rendering. This may not be the best way to accomplish this task however, it should work.
First I created a structure to hold your data for parsing from text file:
public struct Data {
public Data(float x, float y, float value){
X = x;
Y = y;
Value = value;
}
public float Value;
public float X;
public float Y;
}
I then initialized the color palette based on your above image (reversed because I messed up the ordering initially):
Color[] Colors;
private void InitColors()
{
Colors = new Color[20];
Colors [19] = new Color (230 / 255f, 29 / 255f, 0 / 255f, 1);
Colors [18] = new Color (230 / 255f, 74 / 255f, 0 / 255f, 1);
Colors [17] = new Color (230 / 255f, 119 / 255f, 0 / 255f, 1);
Colors [16] = new Color (230 / 255f, 164 / 255f, 0 / 255f, 1);
Colors [15] = new Color (230 / 255f, 207 / 255f, 0 / 255f, 1);
Colors [14] = new Color (185 / 255f, 207 / 255f, 0 / 255f, 1);
Colors [13] = new Color (140 / 255f, 207 / 255f, 0 / 255f, 1);
Colors [12] = new Color (94 / 255f, 207 / 255f, 0 / 255f, 1);
Colors [11] = new Color (49 / 255f, 207 / 255f, 23 / 255f, 1);
Colors [10] = new Color (3 / 255f, 207 / 255f, 73 / 255f, 1);
Colors [9] = new Color (0 / 255f, 207 / 255f, 173 / 255f, 1);
Colors [8] = new Color (0 / 255f, 198 / 255f, 223 / 255f, 1);
Colors [7] = new Color (0 / 255f, 153 / 255f, 230 / 255f, 1);
Colors [6] = new Color (0 / 255f, 108 / 255f, 230 / 255f, 1);
Colors [5] = new Color (0 / 255f, 63 / 255f, 230 / 255f, 1);
Colors [4] = new Color (37 / 255f, 18 / 255f, 230 / 255f, 1);
Colors [3] = new Color (82 / 255f, 0 / 255f, 230 / 255f, 1);
Colors [2] = new Color (128 / 255f, 0 / 255f, 230 / 255f, 1);
Colors [1] = new Color (173 / 255f, 0 / 255f, 230 / 255f, 1);
Colors [0] = new Color (219 / 255f, 1 / 255f, 230 / 255f, 1);
}
I then wrote a parsing function to get the data from your text file into memory, and analyze parts of the data for future use:
private HashSet<float> XValues;
private HashSet<float> YValues;
private List<Data> DataList;
private float Min, MinX, MinY;
private float Max, MaxX, MaxY;
private void ParseData()
{
Min = float.MaxValue;
Max = float.MinValue;
MinX = float.MaxValue;
MaxX = float.MinValue;
MinY = float.MaxValue;
MaxY = float.MinValue;
DataList = new List<Data> ();
XValues = new HashSet<float> ();
YValues = new HashSet<float> ();
if (File.Exists ("data.txt")) {
StreamReader file = new StreamReader ("data.txt");
string line = "";
while ((line = file.ReadLine ()) != null) {
line = line.Replace("(", string.Empty);
line = line.Replace(")", string.Empty);
line = line.Replace(":", ",");
string[] split = line.Split (',');
float x = System.Convert.ToSingle(split [0]);
float y = System.Convert.ToSingle(split [1]);
float value = System.Convert.ToSingle(split [2]);
Data data = new Data (x, y, value);
Min = Mathf.Min (Min, value);
Max = Mathf.Max (Max, value);
MinX = Mathf.Min (MinX, x);
MaxX = Mathf.Max (MaxX, x);
MinY = Mathf.Min (MinY, y);
MaxY = Mathf.Max (MaxY, y);
XValues.Add (x);
YValues.Add (y);
DataList.Add (data);
}
file.Close ();
}
}
Now it is easy to convert the parsed data into a Dataset that we can use:
private Data[,] Data;
private void GenerateDataSet()
{
Data = new Data[XValues.Count, YValues.Count];
for (int x = 0; x < XValues.Count; x++) {
for (int y = 0; y < YValues.Count; y++) {
Data [x, y] = DataList [x + y * XValues.Count];
}
}
}
If we visualize this data now, we get the following:
In order to smooth this out, we are going to add values in between and interpolate based on the distance between known node values:
float[,] Interpolated;
private void Interpolate()
{
int steps = 25;
Interpolated = new float[Data.GetLength (0) * steps, Data.GetLength (1) * steps];
for (int y = 0; y < Interpolated.GetLength (1) - steps; y++) {
for (int x = 0; x < Interpolated.GetLength (0) - steps; x++) {
int x1 = x / steps;
int x2 = x1 + 1;
int y1 = y / steps;
int y2 = y1 + 1;
float distance1 = (new Vector2 (x, y) - new Vector2 (x1 * steps, y1 * steps)).magnitude;
float distance2 = (new Vector2 (x, y) - new Vector2 (x1 * steps, y2 * steps)).magnitude;
float distance3 = (new Vector2 (x, y) - new Vector2 (x2 * steps, y1 * steps)).magnitude;
float distance4 = (new Vector2 (x, y) - new Vector2 (x2 * steps, y2 * steps)).magnitude;
float value1 = Data [x1, y1].Value;
float value2 = Data [x1, y2].Value;
float value3 = Data [x2, y1].Value;
float value4 = Data [x2, y2].Value;
int totalCount = 0;
int count = steps - (int)distance1;
count = Mathf.Max (count, 0);
float total = value1 * count;
totalCount += count;
count = steps - (int)distance2;
count = Mathf.Max (count, 0);
total += value2 * count;
totalCount += count;
count = steps - (int)distance3;
count = Mathf.Max (count, 0);
total += value3 * count;
totalCount += count;
count = steps - (int)distance4;
count = Mathf.Max (count, 0);
total += value4 * count;
totalCount += count;
total = total / (float)totalCount;
Interpolated [x, y] = total;
}
}
}
Now if we draw this interpolated data, we get something that looks a lot more like what you are trying to output. Here is the Texture generation code that was used:
public Texture2D GetHeatMapTexture()
{
int width = Interpolated.GetLength (0);
int height = Interpolated.GetLength (1);
var texture = new Texture2D (width, height);
var pixels = new Color[width * height];
for (var x = 0; x < width; x++)
{
for (var y = 0; y < height; y++)
{
float value = Interpolated [x,y];
float normalized = (value - Min) / (Max - Min);
normalized *= Colors.Length;
int colorValue = (int)normalized;
colorValue = Mathf.Clamp (colorValue, 0, 19);
pixels [x + y * width] = Colors [colorValue];
}
}
texture.SetPixels(pixels);
texture.wrapMode = TextureWrapMode.Clamp;
texture.filterMode = FilterMode.Point;
texture.Apply();
return texture;
}
And here is what it looks like with your provided dataset:
There are probably better ways to accomplish this result, but at least this can provide you with a way to at least get started doing what it is you are trying to do.