ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 12.04.2024
Просмотров: 17
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
}
else
{
y += sy;
}
fu -= 2 * dx;
}
else
{
if (flag)
{
y += sy;
}
else
{
x += sx;
}
fu += 2 * dy;
}
}
return result.ToArray();
}
public static Pixel[] CirclePixels(Point2D center, float radius)
{
List
result = new List
();
float x = 0;
float y = radius;
float delta = 1 - 2 * radius;
float error = 0;
while (y >= x)
{
result.Add(new Pixel((int)(center.X + x), (int)(center.Y + y)));
result.Add(new Pixel((int)(center.X + x), (int)(center.Y - y)));
result.Add(new Pixel((int)(center.X - x), (int)(center.Y + y)));
result.Add(new Pixel((int)(center.X - x), (int)(center.Y - y)));
result.Add(new Pixel((int)(center.X + y), (int)(center.Y + x)));
result.Add(new Pixel((int)(center.X + y), (int)(center.Y - x)));
result.Add(new Pixel((int)(center.X - y), (int)(center.Y + x)));
result.Add(new Pixel((int)(center.X - y), (int)(center.Y - x)));
error = 2 * (delta + y) - 1;
if ((delta < 0) && (error <= 0))
{
delta += 2 * ++x + 1;
continue;
}
if ((delta > 0) && (error > 0))
{
delta -= 2 * --y + 1;
continue;
}
delta += 2 * (++x - --y);
}
return result.ToArray();
}
}
public class CustomCanvas : NotifyPropertyChange
{
protected Bitmap _dataCanvas;
protected ObservableCollection
private readonly int _width;
private readonly int _height;
protected readonly int _length;
protected readonly Color _color;
public Bitmap DataCanvas
{
get { return _dataCanvas; }
private set
{
Set(ref _dataCanvas, value);
}
}
public ObservableCollection
{
get => _graficObjects;
set
{
Set(ref _graficObjects, value);
}
}
public int Width => _width;
public int Height => _height;
public CustomCanvas(int width, int height, int length, Color color)
{
DataCanvas = new Bitmap(width, height);
_width = width;
_height = height;
_length = length;
_color = color;
ClearCanvas(DataCanvas);
GraficObjects.CollectionChanged += GraficObjects_CollectionChanged;
}
protected void ClearCanvas(Bitmap bitmap)
{
using (var g = Graphics.FromImage(bitmap))
{
g.Clear(_color);
}
}
public void DrawPixel(Bitmap bitmap, int x, int y, Color color)
{
if (x >= DataCanvas.Width || y >= DataCanvas.Height || x <= 0 || y <= 0)
{
return;
}
bitmap.SetPixel(x, y, color);
}
public void DrawGraficObject(IGraficObject graficObject)
{
Bitmap result = new Bitmap(Width, Height);
ClearCanvas(result);
if (!_graficObjects.Any(p => p.Id == graficObject.Id))
{
_graficObjects.Add(graficObject);
graficObject.PropertyChanged += GraficObject_PropertyChanged;
}
RedrawCanvas(result);
DataCanvas = result;
}
private void RedrawCanvas(Bitmap bitmap)
{
foreach (IGraficObject graficObject in _graficObjects)
{
Pixel[] pixels = null;
switch (graficObject)
{
case IFigure3D f3D:
Point3D[] points = ProjectionService.Project(f3D, _camera);
pixels = RasterizeService.GetPixels(points, f3D.Edges, f3D.AlgType);
break;
case IFigure2D f2D:
case IGraficObject go:
default:
pixels = graficObject.GetPixels();
break;
}
DrawPixels(bitmap, pixels, graficObject.Color);
}
}
public void DrawPixels(Bitmap bitmap, Pixel[] pixels, Color color)
{
foreach (Pixel p in pixels)
{
DrawPixel(bitmap, p.X, p.Y, color);
}
}
private void GraficObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
DrawGraficObject(sender as IGraficObject);
}
public void Move(IFigure2D figure, float dx, float dy)
{
figure.Move(dx, dy);
DrawGraficObject(figure);
}
public void Scale(IFigure2D figure, float sx, float sy)
{
figure.Scale(sx, sy);
DrawGraficObject(figure);
}
public void Rotate(IFigure2D figure, float angle)
{
figure.Rotate(angle);
DrawGraficObject(figure);
}
public void Move(IFigure3D figure, float dx, float dy, float dz)
{
figure.Move(dx, dy, dz);
DrawGraficObject(figure);
}
public void Scale(IFigure3D figure, float sx, float sy, float sz)
{
figure.Scale(sx, sy, sz);
DrawGraficObject(figure);
}
public void Rotate(IFigure3D figure, float ax, float ay, float az)
{
figure.Rotate(ax, ay, az);
DrawGraficObject(figure);
}
private void GraficObjects_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged(nameof(GraficObjects));
}
}
Пример работы программы
Главное окно приложения изображено Рисунок 8 – Главное окно программы.
Рисунок 8 – Главное окно программы
Окно добавления фигур изображено Рисунок 9 – Окно добавления фигуры.
Рисунок 9 – Окно добавления фигуры
Добавление линии изображено Рисунок 10 – Добавление линии.
Рисунок 10 – Добавление линии
Добавление куба изображено Рисунок 11 – Добавление .
Рисунок 11 – Добавление куба
Результат добавления фигур изображён Рисунок 12 – .
Рисунок 12 – Результат добавления фигур
Результат масштабирования линии изображён Рисунок 13 – .
Рисунок 13 – Результат масштабирования линии
Смещение линии изображено Рисунок 14 – Смещение линии изображено.
Рисунок 14 – Смещение линии изображено
Поворот линии изображён Рисунок 15 – Поворот линии.
Рисунок 15 – Поворот линии
Результат масштабирования куба изображён Рисунок 16 – Результат масштабирования куба.
Рисунок 16 – Результат масштабирования куба
Смещение куба изображено Рисунок 17 – Смещение куба.
Рисунок 17 – Смещение куба
Результат поворота куба изображён Рисунок 18 – Результат поворота куба.
Рисунок 18 – Результат поворота куба
Ответы на контрольные вопросы
-
Что такое афинные преобразования?
Аффинными преобразованиями называют три базовые операции:
-
перенос (перемещение) изображения; -
масштабирование (увеличение или уменьшение размеров) изображения; -
поворот изображения (употребляют также термины вращение, изменение ориентации).
-
С помощью каких формул задаются афинные преобразования?
Двумерные аффинные преобразования
Параллельный перенос
Масштабирование
Поворот
-
Приведите пример расчетов двумерных афинных преобразований для отрезка (координаты выбрать самостоятельно)
P1 = [10 ; 20]
P2 = [30 ; 50]
Перенос по x на 10, по y на 12
x′1 = 10 +10 = 20
y′1 = 20 +12 = 32
x′2 = 30 +10 = 40
y′2 = 50 +12 = 62
P′1 = [20 ; 32]
P′2 = [40 ; 62]
Масштабирование в 1.5 по обеим координатам
x′1 = 10 * 1.5 = 15
y′1 = 20 * 1.5 = 30
x′2 = 30 * 1.5 = 45
y′2 = 50 * 1.5 = 75
P′1 = [15 ; 30]
P′2 = [45 ; 75]
Поворот на 75⁰
x′1 = 10 * 0.259 – 30 * 0.966 = -16.73
y′1 = 10 * 0.966 + 30 * 0.259 = 14.836
x′2 = 30 * 0.259 – 50 * 0.966 = -40.532
y′2 = 30 * 0.966 + 50 * 0.259 = 41.919
P′1 = [-16.73 ; 14.836]
P′2 = [-40.532 ; 41.919]