public bool Equals(Vector2Int p) {
			// If parameter is null return false:
			if ((object)p == null) {
				return false;
			}
			
			// Return true if the fields match:
			return (x == p.x) && (y == p.y);
		}
		public static Texture2D Create(Texture2D map, HeatmapResult.Point[] points, Vector2 size) {

			float maxWeight = 0f;
			for (int i = 0; i < points.Length; ++i) {

				if (points[i].weight > maxWeight) {

					maxWeight = (float)points[i].weight;

				}

			}

			var radius = HeatmapVisualizer.GetRadius();

			if (size == Vector2.zero) {

				return null;

			}

			// Create new texture
			// Texture2D map = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);	
			if (map == null) {

				map = new Texture2D((int)size.x, (int)size.y, TextureFormat.ARGB32, false);

			}

			// Set texture to alpha-fied state
			map.SetPixels(HeatmapVisualizer.ColorArray(new Color(1f, 1f, 1f, 0f), map.width * map.height), 0);

			/*** Generate Grayscale Values ***/
			{
				int x2;							// the offset x val in img coordinates
				int y2;							// the offset y val in img coordinates (0,0) - (maxX, maxY)
				float pointAlpha = .9f;			// The alpha that the darkest pixel will be in a point.
				Color color = new Color(1f, 1f, 1f, pointAlpha);
				int lineWidth = 1;//(int)(radius * .05f);
				Dictionary<Vector2Int, Color> pixelAlpha = new Dictionary<Vector2Int, Color>();
				
				for (int i = 0; i < points.Length; ++i) {			// generate alpha add for each point and a specified circumference

					pixelAlpha.Clear();
					var weight = points[i].weight / maxWeight;
					pointAlpha = weight;

					for (int r = 0; r < radius; r += lineWidth) {	// draw and fill them circles

						for (int angle = 0; angle < 360; ++angle) {

							x2 = (int)(r * Mathf.Cos(angle)) + (int)(points[i].realPoint.x);
							y2 = (int)(r * Mathf.Sin(angle)) + (int)(points[i].realPoint.y);
							
							// This could be sped up
							for (int y = y2; y > y2 - lineWidth; --y) {

								for (int x = x2; x < x2 + lineWidth; ++x) {

									var coord = new Vector2Int(x, y);
									if (pixelAlpha.ContainsKey(coord) == true) {

										pixelAlpha[coord] = color;

									} else {

										pixelAlpha.Add(new Vector2Int(x, y), color);

									}

								}	

							}

						}

						color = new Color(color.r, color.g, color.b, color.a - (pointAlpha / ((float)radius / lineWidth)));

					}
					
					// Since the radial fill code overwrites it's own pixels, make sure to only add finalized alpha to
					// old values.
					foreach (KeyValuePair<Vector2Int, Color> keyval in pixelAlpha) {

						var coord = keyval.Key;
						Color previousColor = map.GetPixel((int)coord.x, (int)coord.y);
						Color newColor = keyval.Value;
						map.SetPixel(coord.x, coord.y, new Color(newColor.r, newColor.b, newColor.g, newColor.a + previousColor.a));

					}
					
					// Reset color for next point
					color = new Color(color.r, color.g, color.b, pointAlpha);

				}

			}
			
			map.Apply();
			
			map.SetPixels32(Colorize(map.GetPixels32(0)), 0);
			
			map.Apply();
			
			return map;

		}
			public Point(Vector2 point, Vector2Int screenSize, int screenId, LayoutTag tag, WindowComponent component) {

				this.screenId = screenId;
				this.screenWidth = screenSize.x;
				this.screenHeight = screenSize.y;

				this.x = point.x;
				this.y = point.y;

				this.tag = tag;
				
			}
				public void AddPoint(Vector2 point, Vector2Int screenSize, int screenId, LayoutTag tag, WindowComponent component) {

					var newPoint = new Point(point, screenSize, screenId, tag, component);
					this.points.Add(newPoint);
					this.changed = true;

					Analytics.Analytics.SendScreenPoint(screenId, newPoint.screenWidth, newPoint.screenHeight, (byte)newPoint.tag, newPoint.x, newPoint.y);

				}