NetNado
  Найти на сайте:

Учащимся

Учителям



Отчет по лабораторной работе №5 по дисциплине компьютерная графика


МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ

ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Институт кибернетики

Кафедра информатики и проектирования систем

Отчет по лабораторной работе №5
по дисциплине КОМПЬЮТЕРНАЯ ГРАФИКА

Вариант 25

Разработчик:

студент группы 8в83

Сафронов Б.А.


Согласовано:

доцент

Демин А. Ю.

Томск 2011

ПРЕОБРАЗОВАНИЯ В ПРОСТРАНСТВЕ. ПРОЕКЦИИ

Задание:

Реализовать с заданным телом все виды преобразований в пространстве: перенос по осям , отражение относительно основных плоскостей, масштабирование, поворот на заданные углы относительно осей. Предусмотреть восстановление исходной позиции тела. Предусмотреть переключение в различные виды проекций: вид спереди, косоугольные, перспективную. Управление организовать как через интерфейсные элементы (меню, кнопки, строки редактирования и пр.), так и через "горячие" клавиши.

Код программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows.Forms;
namespace _3D_graph

{

class Figure

{

public static int Width, Height;
public Figure(int w, int h)

{

Width = w;

Height = h;

}

const int arraySize = 12;
// Матрица ромба для проекции

public static double[,] _Diamond = new double[arraySize, 4] { { 0, 0, 0, 1},

{ 0, 0,-50, 1},

{ 30, 0,-80, 1},

{ 80, 0, -80, 1},

{ 80, 0, 0, 1},
{ 0, 80, 0, 1},

{ 0, 80,-80, 1},

{ 80, 80,-80, 1},

{ 80, 80, -30, 1},

{ 50, 80, 0, 1},
{ 0, 30, -80, 1},

{ 80, 50, 0, 1}
};
// Матрица ромба для преобразований без проекции

public static double[,] _WorkingDiamond = (double[,])_Diamond.Clone();
// Матрица ромба для восстановления

public static double[,] _RecoveredDiamond = (double[,])_Diamond.Clone();
// Матрица для перевода ромба в проекцию

public static double[,] _ProjectionMatrixStand = new double[4, 4] {{ 1, 0, 0, 0},

{ 0, 1, 0, 0},

{ 0, 0, 1, 0},

{ 0, 0, 0, 1}};
public static double[,] _ProjectionMatrixPersp = new double[4, 4] {{ 1, 0, 0, 0},

{ 0, 1, 0, 0},

{ 0, 0, 1, 0.005},

{ 0, 0, 0, 1}};

public static double[,] _ProjectionMatrixKaval = new double[4, 4] {{ 1, 0, 0, 0},

{ 0, 1, 0, 0},

{ Math.Cos(Math.PI * 5 / 45.0), Math.Sin(Math.PI * 5 / 45.0), 0, 0},

{ 0, 0, 0, 1}};
// Матрица масштабирования, везде стоит значение 1, потому что значение масштаба будет присваиваться в функции

public static double[,] _Zoom = new double[4, 4] {{ 1, 0, 0, 0},

{ 0, 1, 0, 0},

{ 0, 0, 1, 0},

{ 0, 0, 0, 1}};

// Матрица поворота

public static double o = Math.PI * 5 / 180.0;

public static double[,] _Rotate = new double[3, 3] { { Math.Cos(o), Math.Sin(o), Math.Sin(o)},

{ -Math.Sin(o), Math.Cos(o), Math.Sin(o)},

{ Math.Sin(o), -Math.Sin(o), Math.Cos(o)} };


/*

* Перенос фигуры в условный центр координат

*/

public static void ToScreen(double[,] Matrix)

{

for (int i = 0; i < arraySize; i++)

{

Matrix[i, 0] = Width / 2 + Matrix[i, 0];

Matrix[i, 1] = Height / 2 - Matrix[i, 1];

}

}
/*

* Перенос фигуры в рабочую точку

*/

public static void ToCoor(double[,] Matrix)

{

for (int i = 0; i < arraySize; i++)

{

Matrix[i, 0] = Width / 2 - Matrix[i, 0];

Matrix[i, 1] = Height / 2 - Matrix[i, 1];

}

}
/*

* Перевод изображения в центральную одноточечную проекцию

*/

public static void ToProjection(double[,] Matrix, int projection)

{

if (projection == 1)

{

for (int i = 0; i < arraySize; i++)

{

for (int j = 0; j < 4; j++)

{

Matrix[i, j] = Matrix[i, 0] * _ProjectionMatrixStand[0, j] +

Matrix[i, 1] * _ProjectionMatrixStand[1, j] +

Matrix[i, 2] * _ProjectionMatrixStand[2, j] +

Matrix[i, 3] * _ProjectionMatrixStand[3, j];

}

}

for (int i = 0; i < arraySize; i++)

for (int j = 0; j < 4; j++)

Matrix[i, j] = Matrix[i, j] / Matrix[i, 3];

} else if (projection == 2)

{

for (int i = 0; i < arraySize; i++)

{

for (int j = 0; j < 4; j++)

{

Matrix[i, j] = Matrix[i, 0] * _ProjectionMatrixPersp[0, j] +

Matrix[i, 1] * _ProjectionMatrixPersp[1, j] +

Matrix[i, 2] * _ProjectionMatrixPersp[2, j] +

Matrix[i, 3] * _ProjectionMatrixPersp[3, j];

}

}

for (int i = 0; i < arraySize; i++)

for (int j = 0; j < 4; j++)

Matrix[i, j] = Matrix[i, j] / Matrix[i, 3];

} else if (projection == 3)

{

for (int i = 0; i < arraySize; i++)

{

for (int j = 0; j < 4; j++)

{

Matrix[i, j] = Matrix[i, 0] * _ProjectionMatrixKaval[0, j] +

Matrix[i, 1] * _ProjectionMatrixKaval[1, j] +

Matrix[i, 2] * _ProjectionMatrixKaval[2, j] +

Matrix[i, 3] * _ProjectionMatrixKaval[3, j];

}

}

for (int i = 0; i < arraySize; i++)

for (int j = 0; j < 4; j++)

Matrix[i, j] = Matrix[i, j] / Matrix[i, 3];

}

}
/*

* Копирование элементов рабочей матрицы

*/

public static void Trans()

{

for (int i = 0; i < arraySize; i++)

for (int j = 0; j < 4; j++)

_Diamond[i, j] = _WorkingDiamond[i, j];

}
/*

* Сдвиг изображения по осям

*/

public static void Movement(double[,] Matrix, int Value, int axis)

{

if (Value < 0) for (int i = 0; i < arraySize; i++) Matrix[i, axis] = Matrix[i, axis] - 10;

if (Value > 0) for (int i = 0; i < arraySize; i++) Matrix[i, axis] = Matrix[i, axis] + 10;

}
/*

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

*/

public static void Zoom(double[,] Matrix, int axis, double Scale)

{

double[] StartCoor = new double[3];

for (int k = 0; k < 3; k++) StartCoor[k] = Matrix[0, k];
for (int t = 0; t < arraySize; t++)

for (int j = 0; j < 3; j++) Matrix[t, j] = Matrix[t, j] - StartCoor[j];
// Преобразование матрицы масштабирования в соответствии с осью

if (Scale > 0) _Zoom[axis, axis] = Scale;

if (Scale < 0) _Zoom[axis, axis] = -1 / Scale;

if (Scale == 0) MessageBox.Show("Задайте значение масштаба");
for (int i = 0; i < arraySize; i++)

{

for (int j = 0; j < 3; j++)

{

Matrix[i, j] = Matrix[i, 0] * _Zoom[0, j] + Matrix[i, 1] * _Zoom[1, j] + Matrix[i, 2] * _Zoom[2, j] + Matrix[i, 3] * _Zoom[3, j];

}

}
// Возврат матрицы масштабирования в исходный вид

_Zoom[axis, axis] = 1;

for (int t = 0; t < arraySize; t++)

for (int j = 0; j < 3; j++) Matrix[t, j] = Matrix[t, j] + StartCoor[j];

}
/*

* Поворот фигуры

*/

public static void Rotate(double[,] Matrix, int axis, double angle)

{

angle = Math.PI * angle / 180.0;

_Rotate = new double[3, 3] { { (double)Math.Cos(angle), (double)Math.Sin(angle), -(double)Math.Sin(angle)},

{ -(double)Math.Sin(angle), (double)Math.Cos(angle), (double)Math.Sin(angle)},

{ (double)Math.Sin(angle), -(double)Math.Sin(angle), (double)Math.Cos(angle)} };
double[,] RecoveredRotate = new double[3, 3];
// Изменение матрицы поворота, для поворота вокруг заданной оси

for (int j = 0; j < 3; j++)

{

RecoveredRotate[0, j] = _Rotate[axis, j];

_Rotate[axis, j] = 0;

RecoveredRotate[1, j] = _Rotate[j, axis];

_Rotate[j, axis] = 0;

}
_Rotate[axis, axis] = 1;

for (int i = 0; i < arraySize; i++)

{

double x, y, z;

x = Matrix[i, 0];

y = Matrix[i, 1];

z = Matrix[i, 2];
for (int j = 0; j < 3; j++)

{

Matrix[i, j] = x * _Rotate[0, j] + y * _Rotate[1, j] + z * _Rotate[2, j];

}

}

}
/*

* Отражение фигуры

*/

public static void Reflect(double[,] Matrix, int axis)

{

double[,] ReflMatrixXoZ = { {1,0,0},

{0,-1,0},

{0,0,1} };
double[,] ReflMatrixXoY = { {1,0,0},

{0,1,0},

{0,0,-1} };
double[,] ReflMatrixYoZ = { {-1,0,0},

{0,1,0},

{0,0,1} };

if (axis == 0)

{

for (int i = 0; i < arraySize; i++)

{

double x, y, z;

x = Matrix[i, 0];

y = Matrix[i, 1];

z = Matrix[i, 2];
for (int j = 0; j < 3; j++)

{

Matrix[i, j] = x * ReflMatrixXoZ[0, j] + y * ReflMatrixXoZ[1, j] + z * ReflMatrixXoZ[2, j];

}

}

} else

if (axis == 1)

{

for (int i = 0; i < arraySize; i++)

{

double x, y, z;

x = Matrix[i, 0];

y = Matrix[i, 1];

z = Matrix[i, 2];
for (int j = 0; j < 3; j++)

{

Matrix[i, j] = x * ReflMatrixXoY[0, j] + y * ReflMatrixXoY[1, j] + z * ReflMatrixXoY[2, j];

}

}

} else

if (axis == 2)

{

for (int i = 0; i < arraySize; i++)

{

double x, y, z;

x = Matrix[i, 0];

y = Matrix[i, 1];

z = Matrix[i, 2];
for (int j = 0; j < 3; j++)

{

Matrix[i, j] = x * ReflMatrixYoZ[0, j] + y * ReflMatrixYoZ[1, j] + z * ReflMatrixYoZ[2, j];

}

}

}

}
/*

* Восстановление ромба в исходное положение

*/

public static void Recover()

{

for (int i = 0; i < arraySize; i++)

for (int j = 0; j < 4; j++) _WorkingDiamond[i, j] = _RecoveredDiamond[i, j];

}

}

}

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;
namespace _3D_graph

{

public partial class Graph : Form

{ Pen figurePen = new Pen(Color.White);

Pen axisPen = new Pen(Color.White);

Object senderNew;

Graphics graph;

Rectangle Rect;

PaintEventArgs q;
/*

* Конструктор класса

*/

public Graph()

{ InitializeComponent();

graph = pictureBox1.CreateGraphics();

Rect = new Rectangle(pictureBox1.Location.X, pictureBox1.Location.Y,

pictureBox1.Width, pictureBox1.Height);

q = new PaintEventArgs(graph, Rect);

this.KeyPreview = true;

Figure.Width = this.pictureBox1.Width;

Figure.Height = this.pictureBox1.Height;

}

private void pictureBox1_Paint(object sender, PaintEventArgs e)

{

e.Graphics.Clear(Color.Black);

e.Graphics.DrawLine(axisPen, (this.pictureBox1.Width / 2), 0, (this.pictureBox1.Width / 2), this.pictureBox1.Height);

e.Graphics.DrawLine(axisPen, 0, (this.pictureBox1.Height / 2), this.pictureBox1.Width, (this.pictureBox1.Height / 2));
if (radioButton1.Checked) Figure.ToProjection(Figure._Diamond, 1);

if (radioButton2.Checked) Figure.ToProjection(Figure._Diamond, 2);

if (radioButton3.Checked) Figure.ToProjection(Figure._Diamond, 3);
Figure.ToScreen(Figure._Diamond);

PaintFigures(7, Figure._Diamond, e);

}

/*

* Рисование фигуры

*/

private void PaintFigures(int Index, double[,] _Matrix, PaintEventArgs e)

{

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[0, 0]), (int)Math.Round(_Matrix[0, 1]), (int)Math.Round(_Matrix[1, 0]), (int)Math.Round(_Matrix[1, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[1, 0]), (int)Math.Round(_Matrix[1, 1]), (int)Math.Round(_Matrix[2, 0]), (int)Math.Round(_Matrix[2, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[2, 0]), (int)Math.Round(_Matrix[2, 1]), (int)Math.Round(_Matrix[3, 0]), (int)Math.Round(_Matrix[3, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[3, 0]), (int)Math.Round(_Matrix[3, 1]), (int)Math.Round(_Matrix[4, 0]), (int)Math.Round(_Matrix[4, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[4, 0]), (int)Math.Round(_Matrix[4, 1]), (int)Math.Round(_Matrix[0, 0]), (int)Math.Round(_Matrix[0, 1]));
e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[5, 0]), (int)Math.Round(_Matrix[5, 1]), (int)Math.Round(_Matrix[6, 0]), (int)Math.Round(_Matrix[6, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[6, 0]), (int)Math.Round(_Matrix[6, 1]), (int)Math.Round(_Matrix[7, 0]), (int)Math.Round(_Matrix[7, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[7, 0]), (int)Math.Round(_Matrix[7, 1]), (int)Math.Round(_Matrix[8, 0]), (int)Math.Round(_Matrix[8, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[8, 0]), (int)Math.Round(_Matrix[8, 1]), (int)Math.Round(_Matrix[9, 0]), (int)Math.Round(_Matrix[9, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[9, 0]), (int)Math.Round(_Matrix[9, 1]), (int)Math.Round(_Matrix[5, 0]), (int)Math.Round(_Matrix[5, 1]));
e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[0, 0]), (int)Math.Round(_Matrix[0, 1]), (int)Math.Round(_Matrix[5, 0]), (int)Math.Round(_Matrix[5, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[3, 0]), (int)Math.Round(_Matrix[3, 1]), (int)Math.Round(_Matrix[7, 0]), (int)Math.Round(_Matrix[7, 1]));
e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[1, 0]), (int)Math.Round(_Matrix[1, 1]), (int)Math.Round(_Matrix[10, 0]), (int)Math.Round(_Matrix[10, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[2, 0]), (int)Math.Round(_Matrix[2, 1]), (int)Math.Round(_Matrix[10, 0]), (int)Math.Round(_Matrix[10, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[10, 0]), (int)Math.Round(_Matrix[10, 1]), (int)Math.Round(_Matrix[6, 0]), (int)Math.Round(_Matrix[6, 1]));
e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[8, 0]), (int)Math.Round(_Matrix[8, 1]), (int)Math.Round(_Matrix[11, 0]), (int)Math.Round(_Matrix[11, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[9, 0]), (int)Math.Round(_Matrix[9, 1]), (int)Math.Round(_Matrix[11, 0]), (int)Math.Round(_Matrix[11, 1]));

e.Graphics.DrawLine(figurePen, (int)Math.Round(_Matrix[11, 0]), (int)Math.Round(_Matrix[11, 1]), (int)Math.Round(_Matrix[4, 0]), (int)Math.Round(_Matrix[4, 1]));

}

/*

* Перемещение по осям

*/

private void NegativeMoveX_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, -1, 0);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

private void PositiveMoveX_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, 1, 0);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

private void NegativeMoveY_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, -1, 1);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

private void PositiveMoveY_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, 1, 1);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

private void PositiveMoveZ_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, 1, 2);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

private void NegativeMoveZ_Click(object sender, EventArgs e)

{ Figure.Movement(Figure._WorkingDiamond, -1, 2);

Figure.Trans();
pictureBox1_Paint(sender, q);

}

/*

* Масштабирование по осям

*/

private void ZoomX_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond,0,2);

Figure.Trans();

pictureBox1_Paint(sender, q);

}
private void ZoomY_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond,1,2);

Figure.Trans();
pictureBox1_Paint(sender, q);

}
private void ZoomZ_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond,2,2);

Figure.Trans();

pictureBox1_Paint(sender, q);

}
private void UnZoomX_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond, 0, -2);

Figure.Trans();

pictureBox1_Paint(sender, q);

}
private void UnZoomY_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond, 1, -2);

Figure.Trans();

pictureBox1_Paint(sender, q);

}
private void UnZoomZ_Click(object sender, EventArgs e)

{

Figure.Zoom(Figure._WorkingDiamond, 2, -2);

Figure.Trans();

pictureBox1_Paint(sender, q);

}
/*

* Вращение вокруг осей

*/

private void RotateX_Click(object sender, EventArgs e)

{ Figure.Rotate(Figure._WorkingDiamond,0, Double.Parse(textBoxAngle.Text));

Figure.Trans();
pictureBox1_Paint(sender, q);

}
private void RotateY_Click(object sender, EventArgs e)

{

Figure.Rotate(Figure._WorkingDiamond, 1, Double.Parse(textBoxAngle.Text));

Figure.Trans();
pictureBox1_Paint(sender, q);

}
private void RotateZ_Click(object sender, EventArgs e)

{

Figure.Rotate(Figure._WorkingDiamond, 2, Double.Parse(textBoxAngle.Text));

Figure.Trans();
pictureBox1_Paint(sender, q);

}

/*

* Восстановление фигуры

*/

private void RecoverMatrix_Click(object sender, EventArgs e)

{ Figure.Recover();

Figure.Trans();
pictureBox1_Paint(sender, q);

}
/*

* Отражение фигуры от плоскостей

*/

private void bReflX_Click(object sender, EventArgs e)

{

Figure.Reflect(Figure._WorkingDiamond, 0);

Figure.Trans();
pictureBox1_Paint(sender, q);

}
private void bReflXoY_Click(object sender, EventArgs e)

{

Figure.Reflect(Figure._WorkingDiamond, 1);

Figure.Trans();
pictureBox1_Paint(sender, q);

}
private void bReflYoZ_Click(object sender, EventArgs e)

{

Figure.Reflect(Figure._WorkingDiamond, 2);

Figure.Trans();
pictureBox1_Paint(sender, q);

}
/*

* Выбор проекции

*/

private void radioButton1_CheckedChanged(object sender, EventArgs e)

{

pictureBox1_Paint(sender, q);

}
private void radioButton2_CheckedChanged(object sender, EventArgs e)

{

pictureBox1_Paint(sender, q);

}
private void radioButton3_CheckedChanged(object sender, EventArgs e)

{

pictureBox1_Paint(sender, q);

}
private void radioButton1_Click(object sender, EventArgs e)

{

pictureBox1_Paint(sender, q);

}
//--------------------------------------------------------------------------------------------------

/*

* Управление с клавиатуры

*/

protected override void OnKeyDown(KeyEventArgs e)

{ base.OnKeyDown(e);

if (e.KeyCode == Keys.X) RotateX_Click(senderNew, q);

if (e.KeyCode == Keys.Y) RotateY_Click(senderNew, q);

if (e.KeyCode == Keys.Z) RotateZ_Click(senderNew, q);
if (e.KeyCode == Keys.NumPad8) PositiveMoveY_Click(senderNew, q);

if (e.KeyCode == Keys.NumPad5) NegativeMoveY_Click(senderNew, q);

if (e.KeyCode == Keys.NumPad4) NegativeMoveX_Click(senderNew, q);

if (e.KeyCode == Keys.NumPad6) PositiveMoveX_Click(senderNew, q);

if (e.KeyCode == Keys.NumPad7) NegativeMoveZ_Click(senderNew, q);

if (e.KeyCode == Keys.NumPad1) PositiveMoveZ_Click(senderNew, q);

}
private void Graph_Load(object sender, EventArgs e)

{ senderNew = sender;

}
private void Graph_Paint(object sender, PaintEventArgs e)

{

pictureBox1_Paint(sender, q);

}

}

}

Результат работы программы:



Рисунок - Скриншот работы программы
Вывод:

В результате проделанной работы были реализованы алгоритмы, производящие все виды преобразований в пространстве, такие как перенос по осям OX, OY, OZ, отражение относительно плоскостей, масштабирование независимо по осям, поворот на заданные углы относительно произвольной точки, указываемой в ходе выполнения программы. При реализации использовалась подпрограмма перемножения матриц, для осуществления поворота, масштабирования и отражения фигуры. Каждая матрица предназначена для определенного вида преобразований. Для преобразования трехмерного изображения в двумерное, использовались матрицы перевода в различные виды проекций (перспективная одноточечная или Кавалье).

страница 1


скачать

Другие похожие работы: