コード例 #1
0
		/// <summary>
		/// Draws a rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the rectangle.</param>
		public static void DrawRectangle(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			DrawLine(x1, y1, x2, y1, ColorAlgorithm, PreviousColors);
			DrawLine(x2, y1, x2, y2, ColorAlgorithm, PreviousColors);
			DrawLine(x2, y2, x1, y2, ColorAlgorithm, PreviousColors);
			DrawLine(x1, y2, x1, y1, ColorAlgorithm, PreviousColors);
		}
コード例 #2
0
		/// <summary>
		/// Fills a rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the rectangle is NOT the background color.</param>
		public static void FillRectangle(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;

			if (!ClipBox(ref x1, ref y1, ref x2, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			bool b;

			while (y1 <= y2)
			{
				DrawScanLine(x1, x2, y1++, ColorAlgorithm, BackgroundColor, out b);
				Collision |= b;
			}
		}
コード例 #3
0
		/// <summary>
		/// Draws a rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		public static void DrawRectangle(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm)
		{
			DrawLine(x1, y1, x2, y1, ColorAlgorithm);
			DrawLine(x2, y1, x2, y2, ColorAlgorithm);
			DrawLine(x2, y2, x1, y2, ColorAlgorithm);
			DrawLine(x1, y2, x1, y1, ColorAlgorithm);
		}
コード例 #4
0
		/// <summary>
		/// Draws a rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the rectangle is NOT the background color.</param>
		public static void DrawRectangle(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			bool b;

			DrawLine(x1, y1, x2, y1, ColorAlgorithm, BackgroundColor, out Collision);

			DrawLine(x2, y1, x2, y2, ColorAlgorithm, BackgroundColor, out b);
			Collision |= b;

			DrawLine(x2, y2, x1, y2, ColorAlgorithm, BackgroundColor, out b);
			Collision |= b;

			DrawLine(x1, y2, x1, y1, ColorAlgorithm, BackgroundColor, out b);
			Collision |= b;
		}
コード例 #5
0
		/// <summary>
		/// Draws a rounded rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="RadiusX">Radius of the corners of the rounded rectangle, along the X-axis.</param>
		/// <param name="RadiusY">Radius of the corners of the rounded rectangle, along the Y-axis.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the rounded rectangle.</param>
		public static void DrawRoundedRectangle(int x1, int y1, int x2, int y2, int RadiusX, int RadiusY, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (RadiusX < 0 || RadiusY < 0)
				return;

			int dx, dy, x, y;
			int dxprim, dyprim;
			double cx, cy, d1, d2, d3, t, uprim, tprim;
			Color cl;

			if (x2 < x1)
			{
				dx = x1;
				x1 = x2;
				x2 = dx;
			}

			if (y2 < y1)
			{
				dy = y1;
				y1 = y2;
				y2 = dy;
			}

			int CenterX1 = x1 + RadiusX;
			int CenterX2 = x2 - RadiusX;
			int CenterY1 = y1 + RadiusY;
			int CenterY2 = y2 - RadiusY;

			if (CenterX1 + 1 <= CenterX2 - 1)
			{
				DrawScanLine(CenterX1 + 1, CenterX2 - 1, y1, ColorAlgorithm, PreviousColors);
				DrawScanLine(CenterX1 + 1, CenterX2 - 1, y2, ColorAlgorithm, PreviousColors);
			}

			if (CenterY1 + 1 <= CenterY2 - 1)
			{
				DrawVerticalLine(x1, CenterY1 + 1, CenterY2 - 1, ColorAlgorithm, PreviousColors);
				DrawVerticalLine(x2, CenterY1 + 1, CenterY2 - 1, ColorAlgorithm, PreviousColors);
			}

			cx = 1.0 / (RadiusX * RadiusX + 0.01);
			cy = 1.0 / (RadiusY * RadiusY + 0.01);

			if (RadiusX > RadiusY)
			{
				dx = -RadiusX;
				dy = 0;
				dxprim = dx + 1;
				dyprim = dy + 1;

				x = CenterX1 + dx;
				y = CenterY2 + dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX1 + dx;
				y = CenterY1 - dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX2 - dx;
				y = CenterY2 + dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX2 - dx;
				y = CenterY1 - dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				t = dx * dx * cx;
				tprim = dxprim * dxprim * cx;
				uprim = dyprim * dyprim * cy;
				do
				{
					d1 = Math.Abs(tprim + dy * dy * cy - 1);  // Pixel to the right
					d2 = Math.Abs(tprim + uprim - 1);         // Pixel down to the right
					d3 = Math.Abs(t + uprim - 1);             // Pixel downwards

					if (d1 <= Math.Min(d2, d3))
					{
						dx++;
						t = tprim;
						dxprim++;
						tprim = dxprim * dxprim * cx;
					}
					else if (d2 <= Math.Min(d1, d3))
					{
						dx++;
						dy++;
						t = tprim;
						dxprim++;
						dyprim++;
						tprim = dxprim * dxprim * cx;
						uprim = dyprim * dyprim * cy;
					}
					else
					{
						dy++;
						dyprim++;
						uprim = dyprim * dyprim * cy;
					}

					x = CenterX1 + dx;
					y = CenterY2 + dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX1 + dx;
					y = CenterY1 - dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX2 - dx;
					y = CenterY2 + dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX2 - dx;
					y = CenterY1 - dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());
				}
				while (dx < 0);
			}
			else
			{
				dx = 0;
				dy = -RadiusY;
				dxprim = dx + 1;
				dyprim = dy + 1;

				x = CenterX2 + dx;
				y = CenterY1 + dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX2 + dx;
				y = CenterY2 - dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX1 - dx;
				y = CenterY1 + dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				x = CenterX1 - dx;
				y = CenterY2 - dy;
				cl = Raster[x, y];
				Raster[x, y] = ColorAlgorithm(x, y, cl);
				PreviousColors.Write(cl.ToArgb());

				t = dx * dx * cx;
				tprim = dxprim * dxprim * cx;
				uprim = dyprim * dyprim * cy;
				do
				{
					d1 = Math.Abs(tprim + dy * dy * cy - 1);  // Pixel to the right
					d2 = Math.Abs(tprim + uprim - 1);         // Pixel down to the right
					d3 = Math.Abs(t + uprim - 1);             // Pixel downwards

					if (d1 <= Math.Min(d2, d3))
					{
						dx++;
						t = tprim;
						dxprim++;
						tprim = dxprim * dxprim * cx;
					}
					else if (d2 <= Math.Min(d1, d3))
					{
						dx++;
						dy++;
						t = tprim;
						dxprim++;
						dyprim++;
						tprim = dxprim * dxprim * cx;
						uprim = dyprim * dyprim * cy;
					}
					else
					{
						dy++;
						dyprim++;
						uprim = dyprim * dyprim * cy;
					}

					x = CenterX2 + dx;
					y = CenterY1 + dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX2 + dx;
					y = CenterY2 - dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX1 - dx;
					y = CenterY1 + dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());

					x = CenterX1 - dx;
					y = CenterY2 - dy;
					cl = Raster[x, y];
					Raster[x, y] = ColorAlgorithm(x, y, cl);
					PreviousColors.Write(cl.ToArgb());
				}
				while (dy < 0);
			}
		}
コード例 #6
0
		/// <summary>
		/// Draws a polygon using an array of coordinates to its nodes.
		/// </summary>
		/// <param name="Points">Points in the polygon.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the polygon.</param>
		public static void DrawPolygon(Point[] Points, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			int c = Points.Length;
			if (c <= 1)
				return;

			Point Prev = Points[c - 1];

			foreach (Point P in Points)
			{
				DrawLine(Prev.X, Prev.Y, P.X, P.Y, ColorAlgorithm, PreviousColors);
				Prev = P;
			}
		}
コード例 #7
0
		/// <summary>
		/// Draws a line between (<paramref name="x1"/>,<paramref name="y"/>) and (<paramref name="x2"/>,<paramref name="y"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x1">X-coordinate of first point.</param>
		/// <param name="x2">X-coordinate of second point.</param>
		/// <param name="y">Y-coordinate.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the line is NOT the background color.</param>
		public static void DrawScanLine(int x1, int x2, int y, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;

			if (!ClipScanLine(ref x1, ref x2, y, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int c = x2 - x1 + 1;
			int p = y * rasterStride + (x1 << 2);
			int o = (y / RasterBlockSize) * rasterBlocksX;
			int p1 = o + (x1 / RasterBlockSize);
			int p2 = o + (x2 / RasterBlockSize);

			byte BgR = BackgroundColor.R;
			byte BgG = BackgroundColor.G;
			byte BgB = BackgroundColor.B;
			byte BgA = BackgroundColor.A;

			byte R, G, B, A;
			Color Color;

			while (c-- > 0)
			{
				R = raster[p++];
				G = raster[p++];
				B = raster[p++];
				A = raster[p];
				p -= 3;

				Color = Color.FromArgb(A, R, G, B);

				if (!Collision && Color != BackgroundColor)
					Collision = true;

				Color = ColorAlgorithm(x1++, y, Color);

				R = Color.R;
				G = Color.G;
				B = Color.B;
				A = Color.A;

				raster[p++] = Color.R;
				raster[p++] = Color.G;
				raster[p++] = Color.B;
				raster[p++] = Color.A;
			}

			c = p2 - p1 + 1;
			while (c-- > 0)
				rasterBlocks[p1++] = true;
		}
コード例 #8
0
		/// <summary>
		/// Fills an ellipse
		/// </summary>
		/// <param name="CenterX">X-coordinate of the center of the ellipse.</param>
		/// <param name="CenterY">Y-coordinate of the center of the ellipse.</param>
		/// <param name="RadiusX">Radius of the ellipse, along the X-axis.</param>
		/// <param name="RadiusY">Radius of the ellipse, along the Y-axis.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the ellipse is NOT the background color.</param>
		public static void FillEllipse(int CenterX, int CenterY, int RadiusX, int RadiusY, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;
			if (RadiusX < 0 || RadiusY < 0)
				return;

			FillRoundedRectangle(CenterX - RadiusX, CenterY - RadiusY, CenterX + RadiusX, CenterY + RadiusY, RadiusX, RadiusY, ColorAlgorithm, BackgroundColor, out Collision);
		}
コード例 #9
0
		/// <summary>
		/// Draws a line between (<paramref name="x1"/>,<paramref name="y1"/>) and (<paramref name="x2"/>,<paramref name="y2"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x1">X-coordinate of first point.</param>
		/// <param name="y1">Y-coordinate of first point.</param>
		/// <param name="x2">X-coordinate of second point.</param>
		/// <param name="y2">Y-coordinate of second point.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the line is NOT the background color.</param>
		public static void DrawLine(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;

			if (!ClipLine(ref x1, ref y1, ref x2, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int dx = x2 - x1;
			int dy = y2 - y1;
			int t;
			double a;
			double step;
			Color cl;

			if (Math.Abs(dx) > Math.Abs(dy))
			{
				if (x2 < x1)
				{
					t = x1;
					x1 = x2;
					x2 = t;

					t = y1;
					y1 = y2;
					y2 = t;

					dx = -dx;
					dy = -dy;
				}

				a = y1;
				step = ((double)dy) / dx;

				while (x1 <= x2)
				{
					t = (int)(a + 0.5);

					cl = Raster[x1, t];
					if (!Collision && (cl != BackgroundColor))
						Collision = true;

					Raster[x1, t] = ColorAlgorithm(x1, t, cl);
					x1++;
					a += step;
				}
			}
			else
			{
				if (y2 < y1)
				{
					t = x1;
					x1 = x2;
					x2 = t;

					t = y1;
					y1 = y2;
					y2 = t;

					dx = -dx;
					dy = -dy;
				}

				a = x1;
				if (dy == 0)    // only occurs if dx==dy==0, i.e. one point. Will cause no error.
					step = 0;
				else
					step = ((double)dx) / dy;

				while (y1 <= y2)
				{
					t = (int)(a + 0.5);

					cl = Raster[t, y1];
					if (!Collision && (cl != BackgroundColor))
						Collision = true;

					Raster[t, y1] = ColorAlgorithm(x1, t, cl);
					y1++;
					a += step;
				}
			}
		}
コード例 #10
0
		/// <summary>
		/// Draws a line between (<paramref name="x1"/>,<paramref name="y1"/>) and (<paramref name="x2"/>,<paramref name="y2"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x1">X-coordinate of first point.</param>
		/// <param name="y1">Y-coordinate of first point.</param>
		/// <param name="x2">X-coordinate of second point.</param>
		/// <param name="y2">Y-coordinate of second point.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the line.</param>
		public static void DrawLine(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (!ClipLine(ref x1, ref y1, ref x2, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int dx = x2 - x1;
			int dy = y2 - y1;
			int t;
			double a;
			double step;
			Color cl;

			if (Math.Abs(dx) > Math.Abs(dy))
			{
				if (x2 < x1)
				{
					t = x1;
					x1 = x2;
					x2 = t;

					t = y1;
					y1 = y2;
					y2 = t;

					dx = -dx;
					dy = -dy;
				}

				a = y1;
				step = ((double)dy) / dx;

				while (x1 <= x2)
				{
					t = (int)(a + 0.5);
					cl = Raster[x1, t];
					PreviousColors.Write(cl.ToArgb());
					Raster[x1, t] = ColorAlgorithm(x1, t, cl);
					x1++;
					a += step;
				}
			}
			else
			{
				if (y2 < y1)
				{
					t = x1;
					x1 = x2;
					x2 = t;

					t = y1;
					y1 = y2;
					y2 = t;

					dx = -dx;
					dy = -dy;
				}

				a = x1;
				if (dy == 0)    // only occurs if dx==dy==0, i.e. one point. Will cause no error.
					step = 0;
				else
					step = ((double)dx) / dy;

				while (y1 <= y2)
				{
					t = (int)(a + 0.5);
					cl = Raster[t, y1];
					PreviousColors.Write(cl.ToArgb());
					Raster[t, y1] = ColorAlgorithm(x1, t, cl);
					y1++;
					a += step;
				}
			}
		}
コード例 #11
0
		/// <summary>
		/// Fills an area limited by a boundary different in color from the current pixel.
		/// </summary>
		/// <param name="x">X-coordinate where to start.</param>
		/// <param name="y">Y-coordinate where to start.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		public static void FillFlood(int x, int y, ProceduralColorAlgorithm ColorAlgorithm)
		{
			LinkedList<Point> Queue = new LinkedList<Point>();
			Color Bg = Raster[x, y];
			Point P;

			Queue = new LinkedList<Point>();
			Queue.AddLast(new Point(x, y));
			Raster[x, y] = ColorAlgorithm(x, y, Bg);

			while (Queue.First != null)
			{
				P = Queue.First.Value;
				Queue.RemoveFirst();

				x = P.X;
				y = P.Y;

				if (x > rasterClipLeft && Raster[x - 1, y] == Bg)
				{
					Raster[x - 1, y] = ColorAlgorithm(x, y, Bg);
					Queue.AddLast(new Point(x - 1, y));
				}

				if (x < rasterClipRight && Raster[x + 1, y] == Bg)
				{
					Raster[x + 1, y] = ColorAlgorithm(x, y, Bg);
					Queue.AddLast(new Point(x + 1, y));
				}

				if (y > rasterClipTop && Raster[x, y - 1] == Bg)
				{
					Raster[x, y - 1] = ColorAlgorithm(x, y, Bg);
					Queue.AddLast(new Point(x, y - 1));
				}

				if (y < rasterClipBottom && Raster[x, y + 1] == Bg)
				{
					Raster[x, y + 1] = ColorAlgorithm(x, y, Bg);
					Queue.AddLast(new Point(x, y + 1));
				}
			}
		}
コード例 #12
0
		/// <summary>
		/// Fills a polygon using an array of coordinates to its nodes.
		/// </summary>
		/// <param name="Points">Points in the polygon.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when filling the polygon.</param>
		public static void FillPolygon(Point[] Points, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			LinkedList<int>[] Edges;
			LinkedList<int> List;
			int MinY, MaxY;
			int y;
			int? PrevX;

			FindEdges(Points, out MinY, out MaxY, out Edges);

			for (y = MinY; y <= MaxY; y++)
			{
				List = Edges[y];
				if (List == null)
					continue;


				PrevX = null;
				foreach (int x in List)
				{
					if (PrevX.HasValue)
					{
						DrawScanLine(PrevX.Value, x, y, ColorAlgorithm, PreviousColors);
						PrevX = null;
					}
					else
						PrevX = x;
				}
			}
		}
コード例 #13
0
		/// <summary>
		/// Fills a polygon using an array of coordinates to its nodes.
		/// </summary>
		/// <param name="Points">Points in the polygon.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the polygon is NOT the background color.</param>
		public static void FillPolygon(Point[] Points, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			LinkedList<int>[] Edges;
			LinkedList<int> List;
			int MinY, MaxY;
			int y;
			int? PrevX;
			bool Collision2;

			FindEdges(Points, out MinY, out MaxY, out Edges);

			Collision = false;
			for (y = MinY; y <= MaxY; y++)
			{
				List = Edges[y];
				if (List == null)
					continue;


				PrevX = null;
				foreach (int x in List)
				{
					if (PrevX.HasValue)
					{
						DrawScanLine(PrevX.Value, x, y, ColorAlgorithm, BackgroundColor, out Collision2);
						Collision |= Collision2;
						PrevX = null;
					}
					else
						PrevX = x;
				}
			}
		}
コード例 #14
0
		/// <summary>
		/// Fills a rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when filling the rectangle.</param>
		public static void FillRectangle(int x1, int y1, int x2, int y2, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (!ClipBox(ref x1, ref y1, ref x2, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			while (y1 <= y2)
				DrawScanLine(x1, x2, y1++, ColorAlgorithm, PreviousColors);
		}
コード例 #15
0
		/// <summary>
		/// Draws a line between (<paramref name="x1"/>,<paramref name="y"/>) and (<paramref name="x2"/>,<paramref name="y"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x1">X-coordinate of first point.</param>
		/// <param name="x2">X-coordinate of second point.</param>
		/// <param name="y">Y-coordinate.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the line.</param>
		public static void DrawScanLine(int x1, int x2, int y, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (!ClipScanLine(ref x1, ref x2, y, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int c = x2 - x1 + 1;
			int p = y * rasterStride + (x1 << 2);
			int o = (y / RasterBlockSize) * rasterBlocksX;
			int p1 = o + (x1 / RasterBlockSize);
			int p2 = o + (x2 / RasterBlockSize);

			byte R, G, B, A;
			Color Color;

			while (c-- > 0)
			{
				R = raster[p++];
				G = raster[p++];
				B = raster[p++];
				A = raster[p];
				p -= 3;

				Color = Color.FromArgb(A, R, G, B);
				PreviousColors.Write(Color.ToArgb());
				Color = ColorAlgorithm(x1++, y, Color);

				raster[p++] = Color.R;
				raster[p++] = Color.G;
				raster[p++] = Color.B;
				raster[p++] = Color.A;
			}

			c = p2 - p1 + 1;
			while (c-- > 0)
				rasterBlocks[p1++] = true;
		}
コード例 #16
0
		/// <summary>
		/// Draws an ellipse
		/// </summary>
		/// <param name="CenterX">X-coordinate of the center of the ellipse.</param>
		/// <param name="CenterY">Y-coordinate of the center of the ellipse.</param>
		/// <param name="RadiusX">Radius of the ellipse, along the X-axis.</param>
		/// <param name="RadiusY">Radius of the ellipse, along the Y-axis.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		public static void DrawEllipse(int CenterX, int CenterY, int RadiusX, int RadiusY, ProceduralColorAlgorithm ColorAlgorithm)
		{
			if (RadiusX < 0 || RadiusY < 0)
				return;

			DrawRoundedRectangle(CenterX - RadiusX, CenterY - RadiusY, CenterX + RadiusX, CenterY + RadiusY, RadiusX, RadiusY, ColorAlgorithm);
		}
コード例 #17
0
		/// <summary>
		/// Draws a line between (<paramref name="x"/>,<paramref name="y1"/>) and (<paramref name="x"/>,<paramref name="y2"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x">X-coordinate</param>
		/// <param name="y1">Y-coordinate of first point.</param>
		/// <param name="y2">Y-coordinate of second point.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the line is NOT the background color.</param>
		public static void DrawVerticalLine(int x, int y1, int y2, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;

			if (!ClipVerticalLine(x, ref y1, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int c = y2 - y1 + 1;
			int p = y1 * rasterStride + (x << 2);
			int o = (x / RasterBlockSize);
			int p1 = (y1 / RasterBlockSize) * rasterBlocksX + o;
			int p2 = (y2 / RasterBlockSize) * rasterBlocksX + o;
			int delta = rasterStride - 4;

			byte BgR = BackgroundColor.R;
			byte BgG = BackgroundColor.G;
			byte BgB = BackgroundColor.B;
			byte BgA = BackgroundColor.A;

			byte R, G, B, A;
			Color Color;

			while (c-- > 0)
			{
				R = raster[p++];
				G = raster[p++];
				B = raster[p++];
				A = raster[p];
				p -= 3;

				Color = Color.FromArgb(A, R, G, B);

				if (!Collision && Color != BackgroundColor)
					Collision = true;

				Color = ColorAlgorithm(x, y1++, Color);

				R = Color.R;
				G = Color.G;
				B = Color.B;
				A = Color.A;

				raster[p++] = Color.R;
				raster[p++] = Color.G;
				raster[p++] = Color.B;
				raster[p++] = Color.A;
				p += delta;
			}

			while (p1 < p2)
			{
				rasterBlocks[p1] = true;
				p1 += rasterBlocksX;
			}
		}
コード例 #18
0
		/// <summary>
		/// Fills an ellipse
		/// </summary>
		/// <param name="CenterX">X-coordinate of the center of the ellipse.</param>
		/// <param name="CenterY">Y-coordinate of the center of the ellipse.</param>
		/// <param name="RadiusX">Radius of the ellipse, along the X-axis.</param>
		/// <param name="RadiusY">Radius of the ellipse, along the Y-axis.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when filling the ellipse.</param>
		public static void FillEllipse(int CenterX, int CenterY, int RadiusX, int RadiusY, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (RadiusX < 0 || RadiusY < 0)
				return;

			FillRoundedRectangle(CenterX - RadiusX, CenterY - RadiusY, CenterX + RadiusX, CenterY + RadiusY, RadiusX, RadiusY, ColorAlgorithm, PreviousColors);
		}
コード例 #19
0
		/// <summary>
		/// Draws a line between (<paramref name="x"/>,<paramref name="y1"/>) and (<paramref name="x"/>,<paramref name="y2"/>), using the color <paramref name="Color"/>.
		/// </summary>
		/// <param name="x">X-coordinate</param>
		/// <param name="y1">Y-coordinate of first point.</param>
		/// <param name="y2">Y-coordinate of second point.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when drawing the line.</param>
		public static void DrawVerticalLine(int x, int y1, int y2, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (!ClipVerticalLine(x, ref y1, ref y2, rasterClipLeft, rasterClipTop, rasterClipRight, rasterClipBottom))
				return;

			int c = y2 - y1 + 1;
			int p = y1 * rasterStride + (x << 2);
			int o = (x / RasterBlockSize);
			int p1 = (y1 / RasterBlockSize) * rasterBlocksX + o;
			int p2 = (y2 / RasterBlockSize) * rasterBlocksX + o;
			int delta = rasterStride - 4;

			byte R, G, B, A;
			Color Color;

			while (c-- > 0)
			{
				R = raster[p++];
				G = raster[p++];
				B = raster[p++];
				A = raster[p];
				p -= 3;

				Color = Color.FromArgb(A, R, G, B);
				PreviousColors.Write(Color.ToArgb());
				Color = ColorAlgorithm(x, y1++, Color);

				raster[p++] = Color.R;
				raster[p++] = Color.G;
				raster[p++] = Color.B;
				raster[p++] = Color.A;
				p += delta;
			}

			while (p1 < p2)
			{
				rasterBlocks[p1] = true;
				p1 += rasterBlocksX;
			}
		}
コード例 #20
0
		/// <summary>
		/// Fills a rounded rectangle using coordinates of two opposing corners.
		/// </summary>
		/// <param name="x1">X-coordinate of first corner.</param>
		/// <param name="y1">Y-coordinate of first corner.</param>
		/// <param name="x2">X-coordinate of second corner.</param>
		/// <param name="y2">Y-coordinate of second corner.</param>
		/// <param name="RadiusX">Radius of the corners of the rounded rectangle, along the X-axis.</param>
		/// <param name="RadiusY">Radius of the corners of the rounded rectangle, along the Y-axis.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="PreviousColors">Returns an enumerable set of colors representing the colors overwritten when filling the rounded rectangle.</param>
		public static void FillRoundedRectangle(int x1, int y1, int x2, int y2, int RadiusX, int RadiusY, ProceduralColorAlgorithm ColorAlgorithm, BinaryWriter PreviousColors)
		{
			if (RadiusX < 0 || RadiusY < 0)
				return;

			int dx0;
			int dx, dy;
			int dxprim, dyprim;
			double cx, cy, d1, d2, d3, t, uprim, tprim;

			if (x2 < x1)
			{
				dx = x1;
				x1 = x2;
				x2 = dx;
			}

			if (y2 < y1)
			{
				dy = y1;
				y1 = y2;
				y2 = dy;
			}

			int CenterX1 = x1 + RadiusX;
			int CenterX2 = x2 - RadiusX;
			int CenterY1 = y1 + RadiusY;
			int CenterY2 = y2 - RadiusY;

			cx = 1.0 / (RadiusX * RadiusX + 0.01);
			cy = 1.0 / (RadiusY * RadiusY + 0.01);

			if (RadiusX > RadiusY)
			{
				dx0 = dx = -RadiusX;
				dy = 0;
				dxprim = dx + 1;
				dyprim = dy + 1;

				t = dx * dx * cx;
				tprim = dxprim * dxprim * cx;
				uprim = dyprim * dyprim * cy;
				do
				{
					d1 = Math.Abs(tprim + dy * dy * cy - 1);  // Pixel to the right
					d2 = Math.Abs(tprim + uprim - 1);         // Pixel down to the right
					d3 = Math.Abs(t + uprim - 1);             // Pixel downwards

					if (d1 <= Math.Min(d2, d3))
					{
						dx++;
						t = tprim;
						dxprim++;
						tprim = dxprim * dxprim * cx;
					}
					else if (d2 <= Math.Min(d1, d3))
					{
						DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY2 + dy, ColorAlgorithm, PreviousColors);

						if (dy > 0 || CenterY1 < CenterY2)
							DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY1 - dy, ColorAlgorithm, PreviousColors);

						dx0 = ++dx;
						dy++;
						t = tprim;
						dxprim++;
						dyprim++;
						tprim = dxprim * dxprim * cx;
						uprim = dyprim * dyprim * cy;
					}
					else
					{
						DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY2 + dy, ColorAlgorithm, PreviousColors);

						if (dy > 0 || CenterY1 < CenterY2)
							DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY1 - dy, ColorAlgorithm, PreviousColors);

						dx0 = dx;
						dy++;
						dyprim++;
						uprim = dyprim * dyprim * cy;
					}
				}
				while (dx < 0);

				DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY2 + dy, ColorAlgorithm, PreviousColors);
				DrawScanLine(CenterX1 + dx0, CenterX2 - dx0, CenterY1 - dy, ColorAlgorithm, PreviousColors);
			}
			else
			{
				dx = 0;
				dy = -RadiusY;
				dxprim = dx + 1;
				dyprim = dy + 1;

				t = dx * dx * cx;
				tprim = dxprim * dxprim * cx;
				uprim = dyprim * dyprim * cy;
				do
				{
					d1 = Math.Abs(tprim + dy * dy * cy - 1);  // Pixel to the right
					d2 = Math.Abs(tprim + uprim - 1);         // Pixel down to the right
					d3 = Math.Abs(t + uprim - 1);             // Pixel downwards

					if (d1 <= Math.Min(d2, d3))
					{
						dx++;
						t = tprim;
						dxprim++;
						tprim = dxprim * dxprim * cx;
					}
					else if (d2 <= Math.Min(d1, d3))
					{
						DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY1 + dy, ColorAlgorithm, PreviousColors);
						DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY2 - dy, ColorAlgorithm, PreviousColors);

						dx++;
						dy++;
						t = tprim;
						dxprim++;
						dyprim++;
						tprim = dxprim * dxprim * cx;
						uprim = dyprim * dyprim * cy;
					}
					else
					{
						DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY1 + dy, ColorAlgorithm, PreviousColors);
						DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY2 - dy, ColorAlgorithm, PreviousColors);

						dy++;
						dyprim++;
						uprim = dyprim * dyprim * cy;
					}
				}
				while (dy < 0);

				DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY1, ColorAlgorithm, PreviousColors);
				if (CenterY1 < CenterY2)
					DrawScanLine(CenterX2 + dx, CenterX1 - dx, CenterY2, ColorAlgorithm, PreviousColors);
			}

			if (CenterY1 + 1 <= CenterY2 - 1)
				FillRectangle(x1, CenterY1 + 1, x2, CenterY2 - 1, ColorAlgorithm, PreviousColors);
		}
コード例 #21
0
		/// <summary>
		/// Draws a polygon using an array of coordinates to its nodes.
		/// </summary>
		/// <param name="Points">Points in the polygon.</param>
		/// <param name="ColorAlgorithm">Coloring algorithm to use.</param>
		/// <param name="BackgroundColor">Expected background color</param>
		/// <param name="Collision">If any of the pixels overwritten by the polygon is NOT the background color.</param>
		public static void DrawPolygon(Point[] Points, ProceduralColorAlgorithm ColorAlgorithm, Color BackgroundColor, out bool Collision)
		{
			Collision = false;
			int c = Points.Length;
			if (c <= 1)
				return;

			Point Prev = Points[c - 1];
			bool Collision2;

			foreach (Point P in Points)
			{
				DrawLine(Prev.X, Prev.Y, P.X, P.Y, ColorAlgorithm, BackgroundColor, out Collision2);
				Collision |= Collision2;
				Prev = P;
			}
		}