ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 01.04.2024
Просмотров: 40
Скачиваний: 0
0 1 0 0
0,75 0 0,65 0
0 0 0 1
М7:
1 0 0 0
0 1 0 0
0 0 1 0
2 0 -1 1
Составим супер-матрицу Ms=M1*M2*...*M7:
0,6488 -0,4 -0,65 0
0,6998 0,6487 0,2988 0
0,2988 -0,65 0,7025 0
1,0012 0,1588 0,9943 1
Пример2.(программно)
Имеем те же исходные данные, записанные на форме в TextBox (рис.2):
Рис.2. Исходные данные для примера
Нажимаем кнопку "Рассчитать". В текстовом поле справа от таблицы вывелись все расчеты по нахождению единой матрицы преобразований с пояснениями (рис.3).
Рис.3. Промежуточные данные
И, наконец, мы получаем результат, выводимый внизу ListBox (рис.4):
Рис.4. Ответ задачи
Как мы видим, программа выдала тот же результат, что получили и мы при ручном расчете, следовательно, работает она верно. Также расчет осуществляется и для других осей: Х и Z. Расчетные данные заносятся в текстовый файл - textfile. txt.
ЗАКЛЮЧЕНИЕ
При составлении данной курсовой работы изучен алгоритм нахождения единой матрицы преобразований для поворота изображения относительно отрезка, рассмотрен метод Гауса для построения обратной матрицы, изучены методы записи информации в файл и изъятия данных из него в ListBox. Данная курсовая работа позволила расширить имеющийся запас знаний и дала навыки работы на языке программирования С # и с интерфейсом Visual Studio, позволила выявить пробелы, которые в дальнейшем планируется восполнить.
ЛИТЕРАТУРА
-
А. Климов - "C#. Советы программистам"- Москва, издательство «ГелиосАРВ», 2005.
-
Н. Культин - Microsoft Visual C# в задачах и примерах- Москва, издательство «Мир», 2008
-
Окулов С. М. «Программирование в алгоритмах» - Санкт-Петербург, издательство «Диалект »,2002
-
Р.Лафоре -" Объектно-ориентированное программирование в С++"– Москва: УРСС, 2006.
-
http://ru.wikipedia.org/wiki
-
http://mmorpgbb.ru/foegwoeg
ПРИЛОЖЕНИЯ
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace kurs
{
public partial class Form1 : Form
{int a;
double[,] O = new double[1,4];
double[,] B = new double[1,4];
double[,] M1 = new double[4, 4];
double[,] M2 = new double[4, 4];
double[,] M3 = new double[4, 4];
double[,] M4 = new double[4, 4];
double[,] M5 = new double[4, 4];
double[,] C = new double[4, 4];
double[,] M6 = new double[4, 4];
double[,] M7 = new double[4, 4];
public Form1()
{
InitializeComponent();
}
//обратная матрица
public static double[,] Inverse(double[,] matrix)
{
var det = Determinent(matrix);
if (Math.Abs(det - 0) < 0.0000001)
throw new Exception("Если детерминант равен нулю, обратной матрицы не существует");
var algDopMatrix = AlgebraicComplement(matrix);
return Multiply(algDopMatrix, 1 / (double)det);
}
public static double Determinent(double[,] matrix)
{
var rowCount = matrix.GetLength(0);
var colCount = matrix.GetLength(1);
double result = 0;
if (rowCount != colCount)
throw new Exception("Детерминант не квадратной матрицы не существует");
if (rowCount == 1)
return matrix[0, 0];
for (int j = 0; j < colCount; j++)
result += (matrix[0, j] * Determinent(Minor(matrix, 0, j)) * Signum(j));
return result;
}
public static double[,] AlgebraicComplement(double[,] matrix)
{
var rowCount = matrix.GetLength(0);
var colCount = matrix.GetLength(1);
if (rowCount != colCount)
throw new Exception("Нужна квадратная матрица");
var result = new double[rowCount, colCount];
for (int i = 0; i < rowCount; i++)
for (int j = 0; j < colCount; j++)
result[i, j] = Signum(i + j) * Determinent(Minor(matrix, i, j));
result = Transpose(result);
return result;
}
public static double[,] Multiply(double[,] matrix, double number)
{
var rowCount = matrix.GetLength(0);
var colCount = matrix.GetLength(1);
var result = new double[rowCount, colCount];
for (var i = 0; i < rowCount; i++)
for (var j = 0; j < colCount; j++)
result[i, j] = matrix[i, j] * number;
return result;
}
public static double[,] Minor(double[,] matrix, int row, int column)
{
var rowCount = matrix.GetLength(0);
var colCount = matrix.GetLength(1);
var result = new double[rowCount - 1, colCount - 1];
var m = 0;
for (var i = 0; i < rowCount; i++)
{
if (i != row)
{
var n = 0;
for (var j = 0; j < colCount; j++)
{
if (j == column) continue;
result[m, n++] = matrix[i, j];
}
m++;
}
}
return result;
}
private static int Signum(int number)
{
return number % 2 == 0 ? 1 : -1;
}
public static double[,] Transpose(double[,] matrix)
{
var rowCount = matrix.GetLength(0);
var colCount = matrix.GetLength(1);
var transposeMatrix = new double[colCount, rowCount];
for (var i = 0; i < rowCount; i++)
for (var j = 0; j < colCount; j++)
transposeMatrix[i, j] = matrix[j, i];
return transposeMatrix;
}
//---------------------------------------------------------------------------------------
// Умножение вектора В на матрицы
void MultB(double[,] K,double[,] L)
{
double[,] Bn = new double[1, 4];
for (int i = 0; i < 1; i++)
for (int j = 0; j < 4; j++)
{
Bn[i, j] = 0;
for (int s = 0; s < 4; s++)
Bn[i, j] += K[i, s] * L[s, j];
}
for (int i = 0; i < 1; i++)
for (int j = 0; j < 4; j++)
B[i, j] = Bn[i, j];
}
//нахождение матрицы М1
void Matr1()
{
M1[0, 0] = 1; M1[0, 1] = 0; M1[0, 2] = 0; M1[0, 3] = 0;
M1[1, 0] = 0; M1[1, 1] = 1; M1[1, 2] = 0; M1[1, 3] = 0;
M1[2, 0] = 0; M1[2, 1] = 0; M1[2, 2] = 1; M1[2, 3] = 0;
M1[3, 0] = (-1) * O[0, 0]; M1[3, 1] = (-1) * O[0, 1]; M1[3, 2] = (-1) * O[0, 2]; M1[3, 3] = 1;
}
// нахождение матрицы по Х
void MatrpX(double co1,double si1)
{
M2[0, 0] = 1; M2[0, 1] = 0; M2[0, 2] = 0; M2[0, 3] = 0;
M2[1, 0] = 0; M2[1, 1] = co1; M2[1, 2] = si1; M2[1, 3] = 0;
M2[2, 0] = 0; M2[2, 1] = -si1; M2[2, 2] = co1; M2[2, 3] = 0;
M2[3, 0] = 0; M2[3, 1] = 0; M2[3, 2] = 0; M2[3, 3] = 1;
}
//нахождение матрицы по У
void MatrpY(double co1, double si1)
{
M3[0, 0] = co1; M3[0, 1] = 0; M3[0, 2] = -si1; M3[0, 3] = 0;
M3[1, 0] = 0; M3[1, 1] = 1; M3[1, 2] = 0; M3[1, 3] = 0;
M3[2, 0] = si1; M3[2, 1] = 0; M3[2, 2] = co1; M3[2, 3] = 0;
M3[3, 0] = 0; M3[3, 1] = 0; M3[3, 2] = 0; M3[3, 3] = 1;
}
// нахождение матрицы по Z
void MatrpZ(double co1, double si1)
{
M4[0, 0] = co1; M4[0, 1] = si1; M4[0, 2] = 0; M4[0, 3] = 0;
M4[1, 0] = -si1; M4[1, 1] = co1; M4[1, 2] = 0; M4[1, 3] = 0;
M4[2, 0] = 0; M4[2, 1] = 0; M4[2, 2] = 1; M4[2, 3] = 0;
M4[3, 0] = 0; M4[3, 1] = 0; M4[3, 2] = 0; M4[3, 3] = 1;
}
//умножение матриц
void MultAll(double [,] K,double [,] L)
{double[,] Bn = new double[4, 4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
Bn[i, j] = 0;
for (int s = 0; s < 4; s++)
Bn[i, j] += K[i, s] * L[s, j];
}
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
C[i, j] = Bn[i, j];
}
// процедура нахождения единой матрицы для оси Х
void MatrX()
{
System.IO.StreamWriter textFile = new System.IO.StreamWriter(@"textfile.txt");
textFile.WriteLine("Необходимо совместить начало отрезка с началом координат. Для этого умножим начало отрезка на инцидентную ему матрицу:");
Matr1();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M1[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M1[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("Умножив начальную точку О на М1, получим:");
textFile.WriteLine("0 0 0 1");
textFile.WriteLine("Умножив конечную точку В на М1, получим:");
M7 = Inverse(M1);
MultB(B,M1);
for (int i = 0; i < 1; i++)
for (int j = 0; j < 4; j++)
textFile.Write("{0,6} ",Convert.ToString(B[i,j]));
textFile.WriteLine();
textFile.WriteLine("Cовместить конец отрезка с плоскостями XOY (XOZ)");
double hip = Math.Round(Math.Sqrt(Math.Pow(B[0, 1], 2) + Math.Pow(B[0, 2], 2)),4);
double si = Math.Round(B[0, 1] / hip,4);
double co = Math.Round(B[0, 2] / hip,4);
textFile.WriteLine("Гипотенуза = {0,6}, Sin = {1,6}, Cos={2,6}", Convert.ToString(Math.Round(hip, 4)), Convert.ToString(Math.Round(si, 4)), Convert.ToString(Math.Round(co, 4)));
textFile.WriteLine("Применим соответствующую матрицу поворота Rx и получим матрицу М2:");
MatrpX(co,si);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M2[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M2[i, j], 4)));
textFile.WriteLine();
}
M6 = Inverse(M2);
MultAll(M1, M2);
MultB(B,M2);
textFile.WriteLine("Умножив матрицу, соответствующую конечной точке на матрицу M2, получим:");
for (int i = 0; i < 1; i++)
for (int j = 0; j < 4; j++)
textFile.Write("{0,6} ", Convert.ToString(B[i, j]));
textFile.WriteLine();
textFile.WriteLine("Далее необходимо совместить отрезок с осью ОX");
hip = Math.Round(Math.Sqrt(Math.Pow(B[0, 0], 2) + Math.Pow(B[0, 2], 2)), 4);
si = Math.Round(B[0, 2] / hip, 4);
co = Math.Round(B[0, 0] / hip, 4);
textFile.WriteLine("Гипотенуза = {0,6}, Sin = {1,6}, Cos={2,6}", Convert.ToString(Math.Round(hip, 4)), Convert.ToString(Math.Round(si, 4)), Convert.ToString(Math.Round(co, 4)));
MatrpY(co, si);
textFile.WriteLine("Применим соответствующую матрицу поворота Ry и получим матрицу М3:");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M3[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M3[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("Составим матрицу поворота M4 относительно оси ОX на угол {0,4} градусов.", a);
M5 = Inverse(M3);
MultAll(C, M3);
si=Math.Round(Math.Sin(Math.PI*a/180),4);
co = Math.Round(Math.Cos(Math.PI * a/180), 4);
MatrpX(co, si);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M2[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M2[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("Найдем обратные матрицы:");
textFile.WriteLine("М5:");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M5[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M5[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("М6:");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M6[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M6[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("М7:");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M7[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M7[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("Составим супер-матрицу Ms=M1*M2*...*M7:");
MultAll(C, M2);
MultAll(C, M5);
MultAll(C, M6);
MultAll(C, M7);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(C[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(C[i, j],4)));
textFile.WriteLine();
}
textFile.Close();
StreamReader sr = new StreamReader("textfile.txt");
string line;
while ((line = sr.ReadLine()) != null)
{
listBox1.Items.Add(line);
}
}
// процедура нахождения единой матрицы для оси Y
void MatrY()
{
System.IO.StreamWriter textFile = new System.IO.StreamWriter(@"textfile.txt");
textFile.WriteLine("Необходимо совместить начало отрезка с началом координат. Для этого умножим начало отрезка на инцидентную ему матрицу:");
Matr1();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M1[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M1[i, j], 4)));
textFile.WriteLine();
}
textFile.WriteLine("Умножив начальную точку О на М1, получим:");
textFile.WriteLine("0 0 0 1");
textFile.WriteLine("Умножив конечную точку В на М1, получим:");
M7 = Inverse(M1);
MultB(B, M1);
for (int i = 0; i < 1; i++)
for (int j = 0; j < 4; j++)
textFile.Write("{0,6} ", Convert.ToString(B[i, j]));
textFile.WriteLine();
textFile.WriteLine("Cовместить конец отрезка с плоскостями YOX (YOZ)");
double hip = Math.Round(Math.Sqrt(Math.Pow(B[0, 0], 2) + Math.Pow(B[0, 2], 2)), 4);
double si = Math.Round(B[0, 2] / hip, 4);
double co = Math.Round(B[0, 0] / hip, 4);
textFile.WriteLine("Гипотенуза = {0,6}, Sin = {1,6}, Cos={2,6}", Convert.ToString(Math.Round(hip, 4)), Convert.ToString(Math.Round(si, 4)), Convert.ToString(Math.Round(co, 4)));
textFile.WriteLine("Применим соответствующую матрицу поворота Ry и получим матрицу М2:");
MatrpY(co, si);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
if (C[i, j] < 0) textFile.Write("{0,6} ", Convert.ToString(Math.Round(M3[i, j], 2)));
else textFile.Write("{0,6} ", Convert.ToString(Math.Round(M3[i, j], 4)));
textFile.WriteLine();
}
M6 = Inverse(M3);
MultAll(M1, M3);
MultB(B, M3);
textFile.WriteLine("Умножив матрицу, соответствующую конечной точке на матрицу M2, получим:");