Rotation Matrix

Hi everyone, i am currently teaching myself c++ and I'm am trying to create a programme where a user can input a 3-D point and rotate that point by an inputed angle using a rotation matrix. I believe i have successfully managed to overload the multiplication operator to multiply the 3-d point by the rotation matrix. My question is that when i run the code and input the angle i want, the matrix outputs extremely small numbers. Any and all help is greatly appreciated.

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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//class.cpp file

  matrixCALC::matrixCALC()
{
       {
     
     int a[3][3];
     
     for (int i = 0; i < 3; i++)
     {
     for (int j = 0; j < 3; j++)
     {
     a[i][j] = 0;
     }
     }
     }
     
};

void matrixCALC::RTheta(const double & theta,double arrayA[3][3])
{
    int I;
    I=theta*(3.141592654/180);
    
    cin>>I;
    
    
    arrayA[0][0]=cos(I);
    arrayA[0][1]=sin(I);
    arrayA[0][2]=0;
    arrayA[1][0]=sin(I);
    arrayA[1][1]=cos(I);
    arrayA[1][2]=0;
    arrayA[2][0]=0;
    arrayA[2][1]=0;
    arrayA[2][2]=1;
    
    
    
    
};





matrixCALC operator *(matrixCALC p, matrixCALC q)
{
    {
        matrixCALC c;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                c.a[i][j] = 0;
                for (int k = 0; k < 3; k++)
                {
                    c.a[i][j] = c.a[i][j] + p. a[i][k] * q.a[k][j];
                }
            }
        }
        return c;
        
    }
    
    
};

void matrixCALC::getMATRIX()
{
    cout << "Please enter the X,Y then Z value of your point, resecitvly" << endl;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 1; j++)
        {
            cin >> a[i][j];
        }
        
    }
    
};

void matrixCALC::getMATRIX3x3()
{
    cout << "Please enter the X,Y then Z value of your point, resecitvly" << endl;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            cin >> a[i][j];
        }
        
    }
    
};

void matrixCALC::print3x3()
{
    cout << "your point is: " << endl;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            cout << " " << a[i][j] << " ";
        }
        cout << "\n";
    }
    
    
};


void matrixCALC::print()
{
    cout << "your point is: " << endl;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 1; j++)
        {
            cout << " " << a[i][j] << " ";
        }
        cout << "\n";
    }
    
    
}

//class.h file

#pragma once
class matrixCALC
{
public:
    matrixCALC();
    
    void RTheta(const double & theta,double arrayA[3][3]);
    void print();
    void getMATRIX();
    void getMATRIX3x3();
    void print3x3();
    
    friend matrixCALC operator *(matrixCALC, matrixCALC);
    
    
private:
    double theta;
   
    double a[3][3];
    
 
public:
    
    
    
    
    
    
    //~matrixCALC();
};


//main.cpp file
int main()
{
 
    double I;
    double a;
    
    
    matrixCALC object,o,b,c;
    o.getMATRIX();
    o.print();
    
   object.RTheta(I,);
   
    b=o*object
 
    
 
    b.print();
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    cin.get();
    cin.ignore();
    return 0;
    
    
}
Line 22: you definitely don't want your angles in radians truncated to int. I should be a double.

Line 31 has a sign error: should be -sin(I) on the RHS. In general, the columns of the transformation matrix should be the images of the basis vectors after transformation. The resulting matrix should be orthogonal.

Not sure that I can see the difference between print() and print3x3(), or between getMATRIX() and getMATRIX3x3().

Please make that your code sample has all the requisite #include statements. Please do something about your indentation. Also, why do you have so many completely blank lines?
Last edited on
Thanks for your reply, but i'm still not able to have the array defined in the function 'RTheta' multiply by the user inputted 3-d point generated by function 'getMatrix' to have the point rotate?
Post your latest code - including all updates, the required headers (NOT pre-compiled-header includes). Remove all unnecessary routines, sort out the indentation and get rid of the wasted blank lines. Also, for now create a single file so it can be run in cpp.sh: don't separate off the header file until later.

If you want to rotate a POINT, then have a separate POINT class. Don't try to jam it into a matrix class unless you have the facility to change numbers of rows and columns.

In your constructor
matrixCALC::matrixCALC()
why do you try to create a new (and int) array? You should initialise the array that is a data member of the class.

Routine
matrixCALC::RTheta
could actually be an overloaded constructor, which takes a single double (the angle) and creates a rotation matrix.




Last edited on
This is my most recent code, with the output i receive after running it.

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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
//matrixCLASS.cpp

#include<iostream>
#include<string>
#include<math.h>
#include"matrixCALC.h"

using namespace std;

matrixCALC::matrixCALC()
{

};

void matrixCALC::RTheta(const double & theta)
{
	double I;
	double arrayA[3][3];
	I = theta*(3.141592654 / 180);

	arrayA[0][0] = cos(I);
	arrayA[0][1] = sin(I);
	arrayA[0][2] = 0;
	arrayA[1][0] = -sin(I);
	arrayA[1][1] = cos(I);
	arrayA[1][2] = 0;
	arrayA[2][0] = 0;
	arrayA[2][1] = 0;
	arrayA[2][2] = 1;


};


void matrixCALC::RPsi(const double& Psi)
{
	
	double I;
	double arrayB[3][3];
	I = Psi*(3.141592654 / 180);

	arrayB[0][0] = cos(I);
	arrayB[0][1] = 0;
	arrayB[0][2] = sin(I);
	arrayB[1][0] = 0;
	arrayB[1][1] = 0;
	arrayB[1][2] = 0;
	arrayB[2][0] = -sin(I);
	arrayB[2][1] = 1;
	arrayB[2][2] = cos(I);

};

void matrixCALC::RGamma(const double & Gamma)
{
	double I;
	double arrayC[3][3];
	I = Gamma*(3.141592654 / 180);

	arrayC[0][0] = 1;
	arrayC[0][1] = 0;
	arrayC[0][2] = 0;
	arrayC[1][0] = 0;
	arrayC[1][1] = cos(I);
	arrayC[1][2] = -sin(I);
	arrayC[2][0] = 0;
	arrayC[2][1] = sin(I);
	arrayC[2][2] = cos(I);

};

void matrixCALC::RComposite(const double & Gamma, const double & theta, const double & Psi)
{
	double I, Y, X;

	I = theta*(3.141592654 / 180);
	X = Psi*(3.141592654 / 180);
	Y = Gamma*(3.141592654 / 180);

	double arrayD[3][3];

	arrayD[0][0] = cos(I)*cos(X);
	arrayD[0][1] = sin(I)*cos(Y)+cos(I)*sin(X)*sin(Y);
	arrayD[0][2] = sin(I)*sin(Y)-cos(I)*sin(X)*cos(Y);
	arrayD[1][0] = -sin(I)*cos(X);
	arrayD[1][1] = cos(I)*cos(Y)-sin(I)*sin(X)*sin(Y);
	arrayD[1][2] = cos(I)*sin(Y)+sin(I)*sin(X)*cos(Y);
	arrayD[2][0] = sin(X);
	arrayD[2][1] = -cos(X)*sin(Y);
	arrayD[2][2] = cos(X)*cos(Y);


};


matrixCALC operator *(matrixCALC p, matrixCALC q)
{
	{
		matrixCALC c;
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				c.a[i][j] = 0;
				for (int k = 0; k < 3; k++)
				{
					c.a[i][j] = c.a[i][j] + p.a[i][k] * q.a[k][j];
				}
			}
		}
		return c;

	}


};

void matrixCALC::getMATRIX()
{
	cout << "Please enter the X,Y then Z value of your point, resecitvly" << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 1; j++)
		{
			cin >> a[i][j];
		}

	}

};

void matrixCALC::print()
{
	cout << "your 3-D point is: " << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 1; j++)
		{
			cout << " " << a[i][j] << " ";
		}
		cout << "\n";
	}


};

void matrixCALC::printmultiply()
{
	cout << "your rotated point is: " << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 1; j++)
		{
			cout << " " << b[i][j] << " ";
		}
		cout << "\n";
	}


};

//main.cpp

#include "matrixCALC.h"
#include<iostream>
#include<string>
#include<math.h>

using namespace std;

int main()
{
	cout << "This programme allows the user (YOU) to enter a three dimensional point/n and have it rotate by a user inputed angle using matrix trasmforms" << endl;
	cout<<endl;

	double I,q;
	double a;

	matrixCALC object, o, b, c,aa,cc,dd,ee,gg,zz;
	o.getMATRIX();
	o.print();

	cout << "\nNow please enter angles values in the X, Y and Z directions respctivly" << endl;
	cout << "please enter rotation in the X direction" << endl;
	cout << endl;
	cin >> I;
	cout << "now the Y-direction" << endl;
	cout << endl;
	cin >> a;
	cout << "and finally the z direction" << endl;
	cout << endl;
	cin >> q;

	
		if (I != 0 && a == 0 && q == 0)
		{
			object.RTheta(I);

			b = object*o;

			b.printmultiply();

	
		}

		else if (I == 0 && a != 0 && q == 0)
		{
			aa.RPsi(a);

			cc = aa*o;

			cc.printmultiply();

		}

		else if (I == 0 && a == 0 && q != 0)
		{
			dd.RGamma(q);

			ee = dd*o;

			ee.printmultiply();

	

		}

		else if (I != 0 && a != 0 && q != 0)
		{

			gg.RComposite(I, a, q);

			zz = gg*o;

			zz.printmultiply();

		

		}

		else 
		{
			cout << "ERROR, please enter numerical values only" << endl;
			cin >> I >> a >> q;

		}
	

	cin.get();
	cin.ignore();
	return 0;


}

//matrixCLASS.h

#pragma once
class matrixCALC
{
public:
	matrixCALC();

	void RTheta(const double & theta);
	void RPsi(const double& Psi);
	void RGamma(const double& Gamma);
	void RComposite(const double & Gamma, const double & theta, const double & Psi);
	void print();
	void getMATRIX();
	void getMATRIX3x3();
	void print3x3();
	void printmultiply();

	friend matrixCALC operator *(matrixCALC, matrixCALC);


private:
	double theta;
	double gamma;
	double Psi;
	double Composite;
	float size;
	double a[3][3];
	double b[3][1];
	

};



This programme allows the user (YOU) to enter a three dimensional point/n and have it rotate by a user inputed angle using matrix trasmforms

Please enter the X,Y then Z value of your point, resecitvly
1
9
3
your 3-D point is:
 1
 9
 3

Now please enter angles values in the X, Y and Z directions respctivly
please enter rotation in the X direction

45
now the Y-direction

0
and finally the z direction

0
your rotated point is:
 -9.25596e+61
 -9.25596e+61
 -9.25596e+61

If you put it in ONE file (rather than several) it would be possible to test in cpp.sh. Please do that in future.

Your matrix class has no plan at all. You have just added private variables to it, willy-nilly, creating ever more complex structures, adding ever more functions, none of which work.
Add one thing at a time and test it. Look at all the variables you have in a single object:
1
2
3
4
5
6
7
        double theta;
	double gamma;
	double Psi;
	double Composite;
	float size;
	double a[3][3];
	double b[3][1];

One array (possibly with row and column limits) would be OK. The rest is unused and unusable.



Your matrix class appears to contain (amongst a lot of other junk) TWO arrays - one a 3x3 matrix, the other a 3x1 point. It should contain just ONE. I think that, unless you have a
flexible number of rows and columns, it would be better to put column vectors in a separate class.


From the top in main():

matrixCALC object, o;
This creates two objects, one called "object", the other "o". Hmm. The constructor of your matrix class does ... nothing with these.


o.getMATRIX();
This apparently asks for a 3x1 point ... but puts it in the first column of a 3x3 array. Hmm.


o.print();
This outputs your point. Well, actually, it outputs the first column of your 3x3 array.


You then input the three Euler angles.


For your chosen example you then call
object.RTheta(I);
No idea, but I guess your intention was to put it in (one of the) array members of "object". However, in fact you put it in a completely new array which disappears when you leave the function.


b = object*o;
It's actually conceivable this might have worked. However, two of the columns in the relevant array in o are zero, whilst there is currently garbage in (both) arrays of "object".


b.printmultiply();
Why a specialist member function printmultiply()? Why not just print()?


Well that's what happens. It makes no sense. To be honest, I'd start from scratch with a more sensible matrix class built up gradually.



Last edited on
Topic archived. No new replies allowed.