Построить график функции y=x^2. График строится из отрезков и алгоритма Брезенхема - C#
Формулировка задачи:
Построить график функции y=x^2. График строится с помощью отрезков. Для построения отрезков использовать алгоритм Брезенхема.
Решение задачи: «Построить график функции y=x^2. График строится из отрезков и алгоритма Брезенхема»
textual
Листинг программы
interface IPlotter
{
void Plot(int x, int y);
}
class BresenhamsOctantTransformation
{
public Point SwitchToOctantZeroFrom(int octant, Point p)
{
switch (octant)
{
case 0: return new Point(p.X, p.Y);
case 1: return new Point(p.Y, p.X);
case 2: return new Point(p.Y, -p.X);
case 3: return new Point(-p.X, p.Y);
case 4: return new Point(-p.X, -p.Y);
case 5: return new Point(-p.Y, -p.X);
case 6: return new Point(-p.Y, p.X);
case 7: return new Point(p.X, -p.Y);
default: throw new ArgumentOutOfRangeException(nameof(octant));
}
}
public Point SwitchFromOctantZeroTo(int octant, Point p)
{
switch (octant)
{
case 0: return new Point(p.X, p.Y);
case 1: return new Point(p.Y, p.X);
case 2: return new Point(-p.Y, p.X);
case 3: return new Point(-p.X, p.Y);
case 4: return new Point(-p.X, -p.Y);
case 5: return new Point(-p.Y, -p.X);
case 6: return new Point(p.Y, -p.X);
case 7: return new Point(p.X, -p.Y);
default: throw new ArgumentOutOfRangeException(nameof(octant));
}
}
}
class BresenhamsPlotter : IPlotter
{
private BresenhamsOctantTransformation _transformation;
private IPlotter _plotter;
private int _octant;
public BresenhamsPlotter(int octant, IPlotter plotter, BresenhamsOctantTransformation trasformation)
{
_plotter = plotter;
_octant = octant;
_transformation = trasformation;
}
public void Plot(int x, int y)
{
Point output = _transformation.SwitchFromOctantZeroTo(_octant, new Point(x, y));
_plotter.Plot(output.X, output.Y);
}
}
class BresenhamsBasicAlgorithm
{
public void DrawLine(Point start, Point end, IPlotter plotter)
{
if (Math.Abs(end.X - start.X) < 1e-6)
{
DrawVertical(start.X, start.Y, end.Y, plotter);
return;
}
DrawLineImpl(start, end, plotter);
}
private void DrawLineImpl(Point start, Point end, IPlotter plotter)
{
int dx = end.X - start.X;
int dy = end.Y - start.Y;
int d = 2 * dy - dx;
int y = start.Y;
for (int x = start.X; x <= end.X; x++)
{
plotter.Plot(x, y);
if (d > 0)
{
y = y + 1;
d -= dx;
}
d += dy;
}
}
private void DrawVertical(int x, int yStart, int yEnd, IPlotter plotter)
{
int dy = yEnd > yStart ? 1 : -1;
for (int y = yStart; true; y += dy)
{
plotter.Plot(x, y);
if (y == yEnd) break;
}
}
}
class BresenhamsOctantWiseAlgorithm
{
private BresenhamsBasicAlgorithm _basicAlgorithm = new BresenhamsBasicAlgorithm();
private BresenhamsOctantTransformation _transformation = new BresenhamsOctantTransformation();
public void DrawLine(Point start, Point end, IPlotter plotter)
{
if (start.X > end.X)
{
var temp = start;
start = end;
end = temp;
}
int octant = GetOctant(end.X - start.X, end.Y - start.Y);
start = _transformation.SwitchToOctantZeroFrom(octant, start);
end = _transformation.SwitchToOctantZeroFrom(octant, end);
var bresenhamsPlotter = new BresenhamsPlotter(octant, plotter, _transformation);
_basicAlgorithm.DrawLine(start, end, bresenhamsPlotter);
}
private int GetOctant(int dx, int dy)
{
if (dy >= 0)
if (dy <= dx)
return 0;
else
return 1;
else
if (-dy <= dx)
return 7;
else
return 6;
}
}
class StupidPlotter : IPlotter
{
private Graphics _graphics;
private Pen _pen;
public StupidPlotter(Graphics graphics, Pen pen)
{
_graphics = graphics;
_pen = pen;
}
public void Plot(int x, int y)
{
_graphics.DrawEllipse(_pen, x - 0.1f, y - 0.1f, 0.2f, 0.2f);
}
}
class MainForm : Form
{
private Point _start;
private Point _end;
private bool _hold;
public MainForm()
{
base.DoubleBuffered = true;
MouseDown += (_, e) =>
{
if (e.Button != MouseButtons.Left) return;
_hold = true;
_start = _end = e.Location;
Invalidate();
};
MouseUp += (_, e) =>
{
if (e.Button != MouseButtons.Left || !_hold) return;
_hold = false;
_end = e.Location;
Invalidate();
};
MouseMove += (_, e) =>
{
if (!_hold) return;
_end = e.Location;
Invalidate();
};
}
protected override void OnPaint(PaintEventArgs e)
{
var plotter = new StupidPlotter(e.Graphics, Pens.Red);
var bresenhamsAlgorithm = new BresenhamsOctantWiseAlgorithm();
bresenhamsAlgorithm.DrawLine(_start, _end, plotter);
}
}
void Main()
{
Application.Run(new MainForm());
}