Файл: Афинные преобразования.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 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 _graficObjects = new 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 GraficObjects

{

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 – Результат поворота куба

Ответы на контрольные вопросы


  1. Что такое афинные преобразования?

Аффинными преобразованиями называют три базовые операции:

  • перенос (перемещение) изображения;

  • масштабирование (увеличение или уменьшение размеров) изображения;

  • поворот изображения (употребляют также термины вращение, изменение ориентации).


  1. С помощью каких формул задаются афинные преобразования?

Двумерные аффинные преобразования

Параллельный перенос



Масштабирование



Поворот



  1. Приведите пример расчетов двумерных афинных преобразований для отрезка (координаты выбрать самостоятельно)

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]