Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
#1

Компонента w вектора слишком большая - C++

04.09.2014, 01:42. Просмотров 401. Ответов 12
Метки нет (Все метки)

Здавствуйте. Пишу 3д рендеринг: без никаких opengl, directx и прочих api. В общем, как обычно, есть три матрицы: Transformation (состоит из Translation, Rotation, Scaling), View (сделал так, что она является центром пространства, сделал обычный transpose вместо inverse) и пытаюсь сделать Perspective Projection Matrix. Проблема заключается в том, что компонента W выходит намного больше чем компонеты x,y,z; Таким образом выходит что все эти значения приблизительно равны нулю. Получается непонятная белеберда. Пробовал различные матрицы perspective projection:http://www.codinglabs.net/article_world_view_projection_matrix.aspx
http://www.scratchapixel.com/lessons...ection-matrix/
http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html

Значения fieldOfView, near far, translate, scale, lookAt, eye менял по-всякому, всё равно ерунда какая-то.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
void Matrix::BuildTransformationMatrix(bool rebuildAll)
{
    // translation matrix
    translationMatrix[0][0] = 1.0f;
    translationMatrix[1][0] = 0.0f;
    translationMatrix[2][0] = 0.0f;
    translationMatrix[3][0] = 0.0f;
 
    translationMatrix[0][1] = 0.0f;
    translationMatrix[1][1] = 1.0f;
    translationMatrix[2][1] = 0.0f;
    translationMatrix[3][1] = 0.0f;
 
    translationMatrix[0][2] = 0.0f;
    translationMatrix[1][2] = 0.0f;
    translationMatrix[2][2] = 1.0f;
    translationMatrix[3][2] = 0.0f;
 
    translationMatrix[0][3] = translateX;
    translationMatrix[1][3] = translateY;
    translationMatrix[2][3] = translateZ;
    translationMatrix[3][3] = 1.0f;
 
    // rotation matrix
    rotationMatrix[0][0] = cos(angle * pi / 180.0f);
    rotationMatrix[1][0] = 0.0f;
    rotationMatrix[2][0] = -sin(angle * pi / 180.0f);
    rotationMatrix[3][0] = 0.0f;
 
    rotationMatrix[0][1] = 0.0f;
    rotationMatrix[1][1] = -1.0f;
    rotationMatrix[2][1] = 0.0f;
    rotationMatrix[3][1] = 0.0f;
 
    rotationMatrix[0][2] = sin(angle * pi / 180.0f);
    rotationMatrix[1][2] = 0.0f;
    rotationMatrix[2][2] = cos(angle * pi / 180.0f);
    rotationMatrix[3][2] = 0.0f;
 
    rotationMatrix[0][3] = 0.0f;
    rotationMatrix[1][3] = 0.0f;
    rotationMatrix[2][3] = 0.0f;
    rotationMatrix[3][3] = 1.0f;
    
    // scaling matrix
    scalingMatrix[0][0] = scale;
    scalingMatrix[1][0] = 0.0f;
    scalingMatrix[2][0] = 0.0f;
    scalingMatrix[3][0] = 0.0f;
 
    scalingMatrix[0][1] = 0.0f;
    scalingMatrix[1][1] = scale;
    scalingMatrix[2][1] = 0.0f;
    scalingMatrix[3][1] = 0.0f;
 
    scalingMatrix[0][2] = 0.0f;
    scalingMatrix[1][2] = 0.0f;
    scalingMatrix[2][2] = scale;
    scalingMatrix[3][2] = 0.0f;
 
    scalingMatrix[0][3] = 0.0f;
    scalingMatrix[1][3] = 0.0f;
    scalingMatrix[2][3] = 0.0f;
    scalingMatrix[3][3] = 1.0f;
 
    float tempMatrix[4][4];
 
    // calculating temporary matrix
    Algorithms::MultiplyMatrices(translationMatrix, rotationMatrix, tempMatrix);
 
    // calculate transformation matrix
    Algorithms::MultiplyMatrices(tempMatrix, scalingMatrix, transformationMatrix);
 
    if(rebuildAll) BuildFinalMatrix();
    return;
}
 
void Matrix::BuildViewMatrix(bool rebuildAll)
{
    // firstly calculate view. View = normalise(at - eye)
    Vertex at = Vertex(0.0f, 0.0f, 1.0f, 1.0f);
    Vertex eye = Vertex(0.0f, 0.0f, 0.0f, 1.0f);
    Vertex view = at - eye;
    Algorithms::Normalise(view);
 
    // now we calculate right. Right = normalise(up X z)
    Vertex y = Vertex(0.0f, 1.0f, 0.0f, 1.0f);
    Vertex right = Algorithms::CrossProduct(y, view);
    Algorithms::Normalise(right);
 
    // finally we calculate up, Up = normalise(z X x)
    Vertex up = Algorithms::CrossProduct(view, right);
    Algorithms::Normalise(y);
 
    viewMatrix[0][0] = right.x;
    viewMatrix[1][0] = right.y;
    viewMatrix[2][0] = right.z;
    viewMatrix[3][0] = -eye.x;
 
    viewMatrix[0][1] = up.x;
    viewMatrix[1][1] = up.y;
    viewMatrix[2][1] = up.z;
    viewMatrix[3][1] = -eye.y;
 
    viewMatrix[0][2] = view.x;
    viewMatrix[1][2] = view.y;
    viewMatrix[2][2] = view.z;
    viewMatrix[3][2] = -eye.z;
 
    viewMatrix[0][3] = 0.0f;
    viewMatrix[1][3] = 0.0f;
    viewMatrix[2][3] = 0.0f;
    viewMatrix[3][3] = 1.0f;
 
    if (rebuildAll) BuildFinalMatrix();
    return;
}
 
void Matrix::BuildProjectionMatrix(bool rebuildAll)
{
    float fov = 90.0f;
    float s = 1 / (tan(fov * 0.5f * pi / 180));
    float nearPlane = -1.0f;
    float farPlane = 1.0f;
 
    projectionMatrix[0][0] = s;
    projectionMatrix[0][1] = 0.0f;
    projectionMatrix[0][2] = 0.0f;
    projectionMatrix[0][3] = 0.0f;
 
    projectionMatrix[1][0] = 0.0f;
    projectionMatrix[1][1] = s;
    projectionMatrix[1][2] = 0.0f;
    projectionMatrix[1][3] = 0.0f;
 
    projectionMatrix[2][0] = 0.0f;
    projectionMatrix[2][1] = 0.0f;
    projectionMatrix[2][2] = -((farPlane + nearPlane) / (farPlane - nearPlane));
    projectionMatrix[2][3] = -1.0f;
 
    projectionMatrix[3][0] = 0.0f;
    projectionMatrix[3][1] = 0.0f;
    projectionMatrix[3][2] = -(2.0f * farPlane * nearPlane / (farPlane - nearPlane));
    projectionMatrix[3][3] = 0.0f;
    
    if (rebuildAll) BuildFinalMatrix();
    return;
}
 
void Matrix::BuildFinalMatrix()
{
    float tempMatrix[4][4];
    Algorithms::MultiplyMatrices(projectionMatrix, viewMatrix, tempMatrix);
    Algorithms::MultiplyMatrices(tempMatrix, transformationMatrix, finalMatrix);
 
    //Algorithms::MultiplyMatrices(viewMatrix, transformationMatrix, finalMatrix);
}
Вот сам метод перемножения матриц
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Algorithms::MultiplyMatrices(float(&firstMatrix)[4][4], float(&secondMatrix)[4][4], float(&resultMatrix)[4][4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            resultMatrix[i][j] = firstMatrix[i][0] * secondMatrix[0][j] +
                firstMatrix[i][1] * secondMatrix[1][j] +
                firstMatrix[i][2] * secondMatrix[2][j] +
                firstMatrix[i][3] * secondMatrix[3][j];
        }
    }
 
    return;
}
Что я делаю нетак?

Добавлено через 5 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float Matrix::translationMatrix[4][4];
float Matrix::rotationMatrix[4][4];
float Matrix::scalingMatrix[4][4];
float Matrix::transformationMatrix[4][4];
float Matrix::viewMatrix[4][4];
float Matrix::projectionMatrix[4][4];
float Matrix::finalMatrix[4][4];
 
float Matrix::angle = 90.0f;
float Matrix::translateX = 550.0f;
float Matrix::translateY = 350.0f;
float Matrix::translateZ = 1.0f;
float Matrix::scale = 70.0f;
 
const float Matrix::pi = 3.142f;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2014, 01:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Компонента w вектора слишком большая (C++):

Символьной переменной L присвоить значение true, если отрицательная компонента вектора C встретится не позднее, чем у векторов A и B - C++
Даны векторы A, B, C, у каждого из которых есть хотя бы одна отрицатель- ная компонента. Символьной переменной L присвоить значение true,...

Найти сколько элементов первого вектора совпадают с элементами второго вектора - C++
#include &lt;iostream&gt; #include &lt;time.h&gt; #include &lt;vector&gt; #include &lt;set&gt; using namespace std; void main() { ...

Дан список, элементы которого являются координатами вектора. Найти длину вектора - C++
1. Дан список, элементы которого являются координатами вектора в n-мерном пространстве. Найти длину вектора.

Определить количество положительных элементов вектора С(10) и заменить этим значением минимальный элемент вектора А(5) - C++
Ребята помогите пожалуйста с задачкой. Я сам не шарю в C++, но в этом семестре появился этот предмет! И завтра его надо будет сдать :( Буду...

Ошибка с итераторами для целочисленного вектора и вектора структуры - C++
Пытаюсь разобраться с векторами. Для динамической работы с памятью вещь, вроде, замечательная и удобная. Только необходимо использовать...

Заданный вектор А, состоящий из n элементов. Переставить компоненты вектора, размещенные после самого элемента вектора А - C++
Заданный вектор А, состоящий из n элементов. Переставить компоненты вектора, размещенные после самого элемента вектора А на начало, а...

12
IrineK
Заблокирован
04.09.2014, 01:45 #2
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Вот сам метод перемножения матриц
Вложите ещё один цикл для подсчёта суммы.
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
04.09.2014, 01:47  [ТС] #3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const Vertex operator * (const float matrix[4][4], const Vertex& vertex)
{
    return Vertex(matrix[0][0] * vertex.x +
        matrix[0][1] * vertex.y +
        matrix[0][2] * vertex.z +
        matrix[0][3] * vertex.w, 
 
        matrix[1][0] * vertex.x +
        matrix[1][1] * vertex.y +
        matrix[1][2] * vertex.z +
        matrix[1][3] * vertex.w,
 
        matrix[2][0] * vertex.x +
        matrix[2][1] * vertex.y +
        matrix[2][2] * vertex.z +
        matrix[2][3] * vertex.w,
        
        matrix[3][0] * vertex.x +
        matrix[3][1] * vertex.y +
        matrix[3][2] * vertex.z +
        matrix[3][3] * vertex.w);
}
Добавлено через 58 секунд
Цитата Сообщение от IrineK Посмотреть сообщение
Вложите ещё один цикл для подсчёта суммы.
Простите, не совсем понял вас.
0
IrineK
Заблокирован
04.09.2014, 09:34 #4
Цитата Сообщение от Pro100Tom Посмотреть сообщение
не совсем понял
Когда в коде возникают конструкции вида
r = a[0] + a[1] + a[2] + a[3]
очевидно, есть возможность изобразить это циклом.
Иначе, получается говнокод нехороший код
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
04.09.2014, 17:22  [ТС] #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Algorithms::MultiplyMatrices(float(&firstMatrix)[4][4], float(&secondMatrix)[4][4], float(&resultMatrix)[4][4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            resultMatrix[i][j] = 0.0f;
 
            for (int k = 0; k < 4; k++)
            {
                resultMatrix[i][j] += firstMatrix[i][k] * secondMatrix[k][j];
            }
        }
    }
 
    return;
}
Сделал. Теперь ваша очередь. Что не так с моим рендерингом. Если надо могу скинуть весь проект и файл, с которого читаю vertices и faces.
0
IrineK
Заблокирован
04.09.2014, 17:39 #6
Все матрицы тоже задаются циклами. Там есть явные закономерности.
Может быть, в процессе переосмысления и найдется баг.
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
04.09.2014, 20:07  [ТС] #7
Цитата Сообщение от IrineK Посмотреть сообщение
Все матрицы тоже задаются циклами.
Как же мне вот это задать циклом?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// translation matrix
    translationMatrix[0][0] = 1.0f;
    translationMatrix[1][0] = 0.0f;
    translationMatrix[2][0] = 0.0f;
    translationMatrix[3][0] = 0.0f;
 
    translationMatrix[0][1] = 0.0f;
    translationMatrix[1][1] = 1.0f;
    translationMatrix[2][1] = 0.0f;
    translationMatrix[3][1] = 0.0f;
 
    translationMatrix[0][2] = 0.0f;
    translationMatrix[1][2] = 0.0f;
    translationMatrix[2][2] = 1.0f;
    translationMatrix[3][2] = 0.0f;
 
    translationMatrix[0][3] = translateX;
    translationMatrix[1][3] = translateY;
    translationMatrix[2][3] = translateZ;
    translationMatrix[3][3] = 1.0f;
Не вижу ошибки. Без Projection Matrix, то есть если пропускать vertices через transformation и view matrices, то всё работает. Но хотелось бы матрицу перспективной проэкции. Можете сами посчтитать. Вот некоторые значения объекта:
Код
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 21.02.2013 21:53:29

#
# object default
#

v  -1.0552 1.8853 1.8378
v  -1.0110 2.5460 1.7188
v  -0.9699 3.1035 1.3935
v  -1.2661 3.0290 1.3896
v  -0.9381 3.4730 0.9117
v  -0.9197 3.4601 -0.2159
v  -1.3067 3.3626 -0.2211
v  -0.9359 3.0796 -0.6899
v  -1.2321 3.0050 -0.6939
v  -0.9666 2.5147 -1.0034
v  -1.0071 1.8514 -1.1086
v  -1.4094 2.2748 1.7154
v  -1.7060 2.6024 1.3873
v  -1.8999 2.8182 0.9035
v  -1.9615 2.8895 0.3377
v  -1.8815 2.8053 -0.2240
v  -1.6720 2.5784 -0.6961
v  -1.3650 2.2434 -1.0068
v  -1.9908 1.4262 1.3962
v  -1.9471 1.1130 1.4005
v  -2.2720 1.2815 0.9151
v  -2.2149 0.8723 0.9208
v  -2.3642 1.2261 0.3502
v  -2.3024 0.7832 0.3563
v  -2.2536 1.2685 -0.2124
v  -2.1965 0.8593 -0.2068
v  -1.9568 1.4022 -0.6873
v  -1.9131 1.0890 -0.6829
v  -1.4158 1.3458 1.7260
v  -1.7178 0.8858 1.4068
v  -1.9153 0.5755 0.9291
v  -1.9782 0.4619 0.3654
v  -1.8969 0.5625 -0.1985
v  -1.6838 0.8619 -0.6766
v  -1.3714 1.3145 -0.9962
v  -1.0957 1.2220 1.7326
v  -1.1264 0.6571 1.4191
v  -1.1426 0.2766 0.9451
v  -1.1418 0.1384 0.3827
v  -1.1242 0.2636 -0.1824
v  -1.0924 0.6331 -0.6643
v  -1.0513 1.1907 -0.9895
v  -1.5683 1.9789 1.7162
v  -1.9996 2.0556 1.3888
v  -2.2834 2.1038 0.9055
Возьмте любой vertex и попробуйте перемножить на матрицы. Wolfram Alpha вам в помощь. Компонента W получается очень большой.
0
IrineK
Заблокирован
04.09.2014, 20:12 #8
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Как же мне вот это задать циклом?
C++
1
2
3
4
5
6
7
8
9
10
for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
    translationMatrix[i][j] = 0.0f;
 
for (int i = 0; i < 4; i++)
    translationMatrix[i][i] = 1.0f;
 
translationMatrix[0][3] = translateX;
translationMatrix[1][3] = translateY;
translationMatrix[2][3] = translateZ;
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
04.09.2014, 20:24  [ТС] #9
Спасибо, но по-моему - это извращение. Если придётся изменить какое-нибудь значение, то придётся всю структуру цикла переделывать. Да и читабельность нарушается. Помогите мне не с точки зрения техники, а с точки зрения функциональности. Не работает матрица, не знаю, что еще пробовать.
0
IrineK
Заблокирован
04.09.2014, 21:07 #10
Цитата Сообщение от Pro100Tom Посмотреть сообщение
по-моему - это извращение
Согласна
1) создание матриц и заполнение нулями по дефолту логично вынести в отдельную функцию (лучше перейти к классам и доверить это конструктору)
2) translateX, translateY и translateZ - тоже вектор. Что вами не учитывается.

Цитата Сообщение от Pro100Tom Посмотреть сообщение
читабельность нарушается
Почти весело.

Нужны классы "Матрица", "Вектор".
Методы: сложение, умножение (матрица-матрица, матрица-вектор, матрица-число, вектор-число)

Цитата Сообщение от Pro100Tom Посмотреть сообщение
Пишу 3д рендеринг
Когда будут правильные инструменты, действия станут понятными и будут записываться в пару строк.
Без техники незачем это всё городить.
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
04.09.2014, 21:48  [ТС] #11
Цитата Сообщение от IrineK Посмотреть сообщение
Нужны классы "Матрица", "Вектор".
Насчёт вектора, то у меня есть класс Vertex. Считаю, что это более логично, так как вектор - это направленный отрезрок, а я работаю с точками и полигонами. Поправьте, если ошибаюсь. Насчёт матрицы, то у меня тоже есть Matrix класс, только там находятся всякие методы и так далее. Думал о том, чтобы создать матрицу как объект, но потом призадумался:
Код
Matrix matrix; matrix.something[0][0] = 1.0f
Подумал, ну нафиг такую ерунду, лучше напишу float matrix[4][4] и делов. Тем более, я могу через конструктор всю матрицу нулями заполнить. Не делал еще этого. А вот переписать операторы уже перемножения матриц я не могу. Приходится довольствоваться обычным методом.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Matrix::MultiplyMatrices(float(&firstMatrix)[4][4], float(&secondMatrix)[4][4], float(&resultMatrix)[4][4])
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            resultMatrix[i][j] = 0.0f;
 
            for (int k = 0; k < 4; k++)
            {
                resultMatrix[i][j] += firstMatrix[i][k] * secondMatrix[k][j];
            }
        }
    }
 
    return;
}
Добавлено через 3 минуты
Назревает вопрос: стоит ли ради наличия возможности и реализации оператора перемножения матриц создавать сам объект типа Matrix, у которого будет 16 полей или float[4][4]?
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
06.09.2014, 15:06  [ТС] #12
Решил сначала разобраться с ортогональной проекцией. Есть вопрос. На этом сайтеhttp://www.codinglabs.net/article_world_view_projection_matrix.aspx написано
To do the Orthographic projection we have to define the size of the area that the camera can see. This is usually defined with a width and height values for the x and y axis, and a near and far z values for the z axis (Figure 9).
И под ней картинка (вложил файл. называется ortho1.jpg). Потом написано вот это
Given these values we can create the transformation matrix that remaps the box area into the cuboid. The matrix that follows is transforms vectors from View Space into Ortho Projected Space and assumes a right handed coordinates system.
И под этим еще две картикни (orthoMatrix.jpg и ortho2.jpg). На картинке ortho2.jpg видно, что объект находится в кубу, границы которого являются {x,y,z} Э [-1, 1]. (Э - пусть будет "принадлежит промежутку"). Отсюда следует вывод, что все vertices чайника должны находиться в этом промежутке, так? Но у меня этого не происходит.
Заметил, что есть связь между значениями scale в transformation matrix и конечными значениями vertex'ов, после того, как пройдут через projection matrix. Не понимаю, ведь недолжно так быть. Model space - это model space. Он может быть каким угодно, ведь потом мы всё равно конвертируем всё в view space.
Может я ошибься с порядком перемножения? Поправьте меня, если я неправ. Сначала я создаю projection matrix, потом view. Перемножаю projection на view (не наоборот). Потом результат перемножаю на transformation matrix. После этого перемножаю матрицы на vertices.
0
Миниатюры
Компонента w вектора слишком большая   Компонента w вектора слишком большая  
Изображения
 
AlexVRud
459 / 170 / 44
Регистрация: 04.07.2014
Сообщений: 475
08.09.2014, 16:58 #13
1. Использовать массивы фиксированного размера как параметры и результат функции в С++ - очень плохая идея. С ними будут выскакивать различного рода проблемы (преобразование к double**, утечка памяти и т.д.). Лучше их обернут в структуры/классы, да и вообще в С++ удобнее использовать std::vector и std::array

2. У тебя каша с матрицами. "Повернуть относительно центра" и "сдвинуть" не тоже самое, что "сдвинуть" и "повернуть относительно центра". Поэтому у тебя должен быть класс "матрица", для которого определены статические функции для их генерации, определены операции умножения и т.д. Тогда ты сможешь более комфортно с ними работать. Например так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <array>
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <math.h>
 
class Matrix;
 
class Vertex {
public:
  Vertex(std::array<float,4> vector=std::array<float,4>()) : v(vector) {};
 
  std::string to_string() {
    std::stringstream ss;
    ss << std::setprecision(4) << std::fixed;
    for(int i=0; i<4; ++i)
      ss << std::setw(8) << v[i];
    return ss.str();
  };
 
  friend Vertex operator* (const Matrix &M, const Vertex &v);
private:
  std::array<float,4> v;
};
 
class Matrix {
public:
  Matrix(std::array<float,16> matrix=std::array<float,16>()) : A(matrix) {};
 
  static Matrix Translation(float dx, float dy, float dz) {
    return Matrix({ 1.0f, 0.0f, 0.0f,   dx ,
                    0.0f, 1.0f, 0.0f,   dy ,
                    0.0f, 0.0f, 1.0f,   dz ,
                    0.0f, 0.0f, 0.0f, 1.0f });
  };
 
  static Matrix RotateAroundXAxis(float phi) {
    return Matrix({ 1.0f,             0.0f,             0.0f, 0.0f ,
                    0.0f,  (float)cos(phi),  (float)sin(phi), 0.0f ,
                    0.0f, -(float)sin(phi),  (float)cos(phi), 0.0f ,
                    0.0f,             0.0f,             0.0f, 1.0f });
  };
  
  std::string to_string() {
    std::stringstream ss;
    ss << std::setprecision(4) << std::fixed;
    for(int i=0; i<16; ++i) {
      ss << std::setw(8) << A[i];
      if (i%4==3) ss << '\n';
    }
    return ss.str();
  };
 
  friend Vertex operator* (const Matrix &M, const Vertex &v);
  friend Matrix operator* (const Matrix &L, const Matrix &R);
private:
  std::array<float,16> A;
};
 
Matrix operator* (const Matrix &L, const Matrix &R) {
  Matrix M;
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      M.A[i*4+j] = L.A[i*4+0] * R.A[0*4+j] +
                   L.A[i*4+1] * R.A[1*4+j] +
                   L.A[i*4+2] * R.A[2*4+j] +
                   L.A[i*4+3] * R.A[3*4+j];
    };
  };
  return M;
};
 
Vertex operator* (const Matrix &M, const Vertex &v) {
  Vertex result;
  for (int i = 0; i < 4; i++) {
    result.v[i] = M.A[i*4+0] * v.v[0] +
                  M.A[i*4+1] * v.v[1] +
                  M.A[i*4+2] * v.v[2] +
                  M.A[i*4+3] * v.v[3];
  };
  return result;
};
 
int main() {
  Vertex v0({0.0f, 2.0f, 3.0f, 1.0f});
  std::cout << "v0: " << v0.to_string() << std::endl;
  Matrix m1 = Matrix::Translation(0.0f, 1.0f, 1.0f) * Matrix::RotateAroundXAxis(1.0f);
  std::cout << "m1:\n" << m1.to_string() << std::endl;
  Vertex v1 = m1*v0;
  std::cout << "v1: " << v1.to_string() << std::endl;
  Matrix m2 = Matrix::RotateAroundXAxis(1.0f) * Matrix::Translation(0.0f, 1.0f, 1.0f);
  std::cout << "m2:\n" << m2.to_string() << std::endl;
  Vertex v2 = m2*v0;
  std::cout << "v2: " << v2.to_string() << std::endl;
  return 0;
};
Добавлено через 12 минут
К порядку умножения. Тут надо помнить, что умножение матриц (вектор - это тоже матрица) ассоциативно, но не коммутативно. Если ты хочешь передвинуть (T) вектор (v0), а потом его повернуть (R), то справедливо следующее:

v1 = T*v0; v2 = R*v2;
v2 = R*(T*v0)
v2= (R*T)*v0
M=R*T; v2=M*v0
0
08.09.2014, 16:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.09.2014, 16:58
Привет! Вот еще темы с ответами:

STL. Функция, которая будет искать элементы большее среднего арифметического вектора и удалять их из вектора - C++
у меня есть вектор, помогите пожалуйста дописать функцию, которая будет искать элементы большее среднего арифметического вектора и удалять...

Составить главную программу и функцию. Для данного вектора А(М) найти количество неповторяющихся элементов вектора - C++
Здравствуйте. Буду очень благодарен,если кто нибудь напишет два кода к этим задачам. Спасибо за внимание. Задача 1. Составить...

Заданы три вектора a(n), b(m), c(k). Вывести наименование вектора, в котором максимальна сумма четных элементов, стоящих на нечетных местах - C++
Заданы три вектора a(n), b(m), c(k). Вывести наименование вектора, в котором максимальна сумма четных элементов, стоящих на нечетных...

Изменение вектора. Наибольший элемент вектора - C++
Добрый день, нужна оценка кода. Пропустил занятия, делал по теории, опирался на массивы. Скажите, правильно ли реализовано? Создать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru