private static void PlotLineHigh(IScreenBuffer buffer, int x0, int y0, int x1, int y1, Color color) { int dx = x1 - x0; int dy = y1 - y0; int xi = 1; if (dx < 0) { xi = -1; dx = -dx; } int D = 2 * dx - dy; int x = x0; for (int y = y0; y <= y1; y++) { buffer.DrawPixel(x, y, color); if (D > 0) { x = x + xi; D = D - 2 * dy; } D = D + 2 * dx; } }
private static void PlotLineLow(IScreenBuffer buffer, int x0, int y0, int x1, int y1, Color color) { int dx = x1 - x0; int dy = y1 - y0; int yi = 1; if (dy < 0) { yi = -1; dy = -dy; } int D = 2 * dy - dx; int y = y0; for (int x = x0; x <= x1; x++) { buffer.DrawPixel(x, y, color); if (D > 0) { y = y + yi; D = D - 2 * dx; } D = D + 2 * dy; } }
private static void PlotCircleSegments(IScreenBuffer buffer, int xc, int yc, int x, int y, Color color) { buffer.DrawPixel(xc + x, yc + y, color); buffer.DrawPixel(xc - x, yc + y, color); buffer.DrawPixel(xc + x, yc - y, color); buffer.DrawPixel(xc - x, yc - y, color); buffer.DrawPixel(xc + y, yc + x, color); buffer.DrawPixel(xc - y, yc + x, color); buffer.DrawPixel(xc + y, yc - x, color); buffer.DrawPixel(xc - y, yc - x, color); }
public void Render(IScreenBuffer screen, PlayerInfo player) { screen.Clear(); if (_lastScreenSize != screen.Dimensions) { _lastScreenSize = screen.Dimensions; _size = new Point(screen.Dimensions.X, FireHeight); _fireBuffer = new byte[_size.Area()]; InitializeFire(); } var yOffset = screen.Height - FireHeight; for (int y = 0; y < _size.Y; y++) { for (int x = 0; x < _size.X; x++) { var colorIndex = _fireBuffer[y * _size.X + x]; var color = _palette[colorIndex]; screen.DrawPixel(x, yOffset + y, color); } } }
public static void PlotLineSmooth(this IScreenBuffer buffer, int x0, int y0, int x1, int y1, Color baseColor) { void Swap(ref int a, ref int b) { var temp = a; a = b; b = temp; } float FractionalPart(float f) => f - (int)f; float ReciprocalOfFractionalPart(float f) => 1 - FractionalPart(f); float Gamma(float x, float exp) => (float)Pow(x, 1.0f / exp); void DrawPixel(int x, int y) => buffer.DrawPixel(x, y, baseColor); void DrawPixelScale(int x, int y, float intensity) => buffer.AddPixel(x, y, baseColor * Gamma(intensity, GammaExponent)); // Make sure the line runs top to bottom if (y0 > y1) { Swap(ref x0, ref x1); Swap(ref y0, ref y1); } // Draw the initial pixel, which is always exactly intersected by the line and so needs no weighting DrawPixel(x0, y0); var deltaX = x1 - x0; var xDir = 1; if (deltaX < 0) { xDir = -1; deltaX = -deltaX; // make DeltaX positive } var deltaY = y1 - y0; // Guaranteed to be positive since we made sure it goes from top to bottom // Special cases for horizontal, vertical, and diagonal lines if (deltaY == 0) { while (deltaX-- != 0) { x0 += xDir; DrawPixel(x0, y0); } return; } if (deltaX == 0) { do { y0++; DrawPixel(x0, y0); } while (--deltaY != 0); return; } if (deltaX == deltaY) { do { x0 += xDir; y0++; DrawPixel(x0, y0); } while (--deltaY != 0); return; } // line is not horizontal, diagonal, or vertical float gradient = 0; float accumulatedError = 0; bool isYMajorLine = deltaY > deltaX; if (isYMajorLine) { gradient = (float)deltaX / deltaY; while (--deltaY != 0) { accumulatedError += gradient; y0++; DrawPixelScale(x0 + xDir * (int)accumulatedError, y0, ReciprocalOfFractionalPart(accumulatedError)); DrawPixelScale(x0 + xDir * (int)accumulatedError + xDir, y0, FractionalPart(accumulatedError)); } } else { gradient = (float)deltaY / deltaX; while (--deltaX != 0) { accumulatedError += gradient; x0 += xDir; DrawPixelScale(x0, y0 + (int)accumulatedError, ReciprocalOfFractionalPart(accumulatedError)); DrawPixelScale(x0, y0 + (int)accumulatedError + 1, FractionalPart(accumulatedError)); } } // Draw the final pixel, which is always exactly intersected by the line // and so needs no weighting DrawPixel(x1, y1); }
public static void DrawPixel(this IScreenBuffer buffer, Point p, Color c) => buffer.DrawPixel(p.X, p.Y, c);