Using for loop in this equation using c++

Pages: 12
Given equation:S = {(P1 (1-u) + P2u) (1-v)} + {(P3 (1-u) + P4u) v}.

This is an equation to represent triangles, Points P1 (2,2,2) and so on, P2, P3 and P4 are coordinate points and are known.

u and v are scalar quantities which is the input to the equation and S is the output point (a,b,c). The values for u are 0, 0.5 and 1 and for v is 0, 0.5 and 1 as well. So hence there are 9 different cases which would output 9 coordinate points. For example, if u = 0 and v = 0 then one point is obtained. I can write the code for each case but that is to long. Hence can I use a for loop for u and v to get all the nine points. If so then how? This is my first time using C++.

Code:

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
 
   
   #include <math.h>
#include <iostream>
#include <stdio.h>

using namespace std;

//		Definition of structure "v3d" AKA a vector
struct v3d
{
	double X, Y, Z, mag;
};

int main() {

  double P1x, P1y, P1z, P2x, P2y, P2z, P3x, P3y, P3z, P4x, P4y, P4z;
  double u , v;

  P1x = 2;
  P1y = 2;
  P1z = 2;

  P2x = 7;
  P2y = 2;
  P2z = 2;

  P3x = 3;
  P3y = 5;
  P3z = 6;

  P4x = 8;
  P4y = 5;
  P4z = 6;

  u = 0;
  v = 0;

   //   Definition of structure "v3d" AKA a vector

   v3d P1, P2, P3, P4, S;

   P1.X = P1x;
   P1.Y = P1y;
   P1.Z = P1z;
   magnitude(P1);
   cout<<"P1\n";
   pprint(P1);

   P2.X = P2x;
   P2.Y = P2y;
   P2.Z = P2z;
   magnitude(P2);
   cout<<"P2\n";
   pprint(P2);

   P3.X = P3x;
   P3.Y = P3y;
   P3.Z = P3z;
   magnitude(P3);
   cout<<"P3\n";
   pprint(P3);

   P4.X = P4x;
   P4.Y = P4y;
   P4.Z = P4z;
   magnitude(P4);
   cout<<"P4\n";
   pprint(P4);


   S.X = ((P1.X) *(1-u)+(P2.X*u))*(1-v) + (P3.X * (1-u)+ (P4.X*u))*(v);       
   S.Y = ((P1.Y) *(1-u)+(P2.Y*u))*(1-v) + (P3.Y * (1-u)+ (P4.Y*u))*(v);   
   S.Z = ((P1.Z) *(1-u)+(P2.Z*u))*(1-v) + (P3.Z * (1-u)+ (P4.Z*u))*(v);   
   magnitude(S);  
   cout<<"S\n";  
   pprint(S);}  
Last edited on
Please put your code between the code blocks. You can see under format to the right an icon that looks like this <>, choose that one and put your code in there.
closed account (D80DSL3A)
Great news! It appears that you have a v3d class for use here.
You should be able to eliminate a lot of that code.
Surely the v3d class has a constructor which takes 3 doubles and assigns them to the vector elements.
So you could get rid of lines 1-18, 27-29, 34-36, 41-43 and 48-50.
This code should do what all of that does:
v3d P1(2,2,2), P2(7,2,2), P3(3,5,6), P4(8,5,6);
Also, for the purpose of automating multiple calcs in a for loop as you've asked about, declare an array of 3 v3d for the 3 S vectors. Probably a no-arg constructor for v3d is supplied too.
v3d S[3];
Declare arrays for your 3 u's and v's
double u[3] = {0.0, 0.5, 1.0 }, v[3] = {0.0, 0.5, 1.0 }
Also, any v3d class worth its salt will support multiplication by scalars, so you should be able to write the vector equations almost like you would on paper:
Putting it in a for loop, it should look like this:
1
2
3
4
for(int i=0; i<3; ++i}
{
    S[i] = (  P1*(1-u[i] ) +  P2*u[i] )*( 1 - v[i] ) +  (  P3*(1-u[i] ) +  P4*u[i] )* v[i];
}

That should calculate all 3 S vectors.
EDIT: Correction to above equation.
EDIT2: Sorry, I see your v3d struct at the top of your code. It doesn't support much.
You can still go with an array of 3 v3d for use in a for loop, but you'll have to find each element, like in your code:
1
2
3
4
5
for(int i=0; i<3; ++i}
{
    S[i].X = (  P1.X*(1-u[i] ) +  P2.X*u[i] )*( 1 - v[i] ) +  (  P3.X*(1-u[i] ) +  P4.X*u[i] )* v[i];
    // and for Y, Z components
}
Last edited on
Thank you for the tips I had a few questions, I should be actually getting nine points or 9 vectors because there are nine combinations between u and v.

Also don't I have to declare i.
This is my code now :

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
 struct v3d
{
	double X, Y, Z, mag;
};

void pprint(v3d A)
{
     cout<<A.X<<"\t"<<A.Y<<"\t"<<A.Z<<"\t"<<A.mag<<"\n";
}


int main()
{

double P1x, P1y, P1z, P2x, P2y, P2z, P3x, P3y, P3z, P4x, P4y, P4z;
double u[3] = {0.0, 0.5, 1.0 }, v[3] = {0.0, 0.5, 1.0 };

P1x = 2;
P1y = 2;
P1z = 2;

P2x = 7;
P2y = 2;
P2z = 2;

P3x = 3;
P3y = 5;
P3z = 6;

P4x = 8;
P4y = 5;
P4z = 6;

//u = 0;
//v = 0;


v3d P1, P2, P3, P4;
v3d S[3];

       P1.X = P1x;
       P1.Y = P1y;
       P1.Z = P1z;
       magnitude(P1);
       cout<<"P1\n";
       pprint(P1);

       P2.X = P2x;
       P2.Y = P2y;
       P2.Z = P2z;
       magnitude(P2);
       cout<<"P2\n";
       pprint(P2);
       
       P3.X = P3x;
       P3.Y = P3y;
       P3.Z = P3z;
       magnitude(P3);
       cout<<"P3\n";
       pprint(P3);

       P4.X = P4x;
       P4.Y = P4y;
       P4.Z = P4z;
       magnitude(P4);
       cout<<"P4\n";
       pprint(P4);

for(int i=0; i<3; ++i)
{
    S[i].X = (  P1.X*(1-u[i] ) +  P2.X*u[i] )*( 1 - v[i] ) +  (  P3.X*(1-u[i] ) +  P4.X*u[i] )* v[i];
    S[i].Y = (  P1.Y*(1-u[i] ) +  P2.Y*u[i] )*( 1 - v[i] ) +  (  P3.Y*(1-u[i] ) +  P4.Y*u[i] )* v[i];
    S[i].Z = (  P1.Z*(1-u[i] ) +  P2.Z*u[i] )*( 1 - v[i] ) +  (  P3.Z*(1-u[i] ) +  P4.Z*u[i] )* v[i];
   
       cout << endl <<" = "<< S << endl;     
}

system("pause");
    return 0; }


But am not getting the right answer and this is what I get 0x23fd30 for (S.X, S.Y, S.Z)
Last edited on
closed account (D80DSL3A)
Oh yeah. All combos for the 2 variables u, v.
The variable i is declared in the for loops, where it's used.

A nested for loop should do the trick:
Declare 9 S's, and be careful with the index into s[] in the loops:
1
2
3
4
5
6
7
v3d S[9];
for(int i=0; i<3; ++i}
    for(int j=0; j<3; ++j}
    {
        S[3*i+j].X = (  P1.X*(1-u[i] ) +  P2.X*u[i] )*( 1 - v[j] ) +  (  P3.X*(1-u[i] ) +  P4.X*u[i] )* v[j];
        // and for Y, Z components
    }
closed account (D80DSL3A)
I just saw your last post.
Line 75 would display the memory address for S.
It looks like you're using a pprint() to display these v3d objects.
So, shouldn't line 75 be:
pprint(S[i]);?

EDIT: As for correctness of the results.
I have written a "minimally enhanced" version of v3d for this problem, and a test program:
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
#include <iostream>
#include<cmath>
using namespace std;

struct v3d
{
	double X, Y, Z;
	v3d(double x=0.0, double y=0.0, double z=0.0): X(x), Y(y), Z(z) {}
	double mag()const { return sqrt(X*X + Y*Y + Z*Z); }
	v3d operator*(double s)const { return v3d(s*X, s*Y, s*Z); }// supports v3d * scalar only
	v3d operator+(const v3d& v)const { return v3d(X+v.X, Y+v.Y, Z+v.Z); }// v3d + v3d
};
// to support scalar * v3d
v3d operator*( double s, const v3d& v ){ return v*s; }// using the in struct def.
// stream a v3d to output
ostream& operator<<( ostream& os, v3d v )
{
    os << '(' << v.X << ", " << v.Y << ", " << v.Z << ')';
    return os;
}


int main()
{
    v3d P1(2,2,2), P2(7,2,2), P3(3,5,6), P4(8,5,6), S[9];
    double u[3] = {0.0, 0.5, 1.0}, v[3] = {0.0, 0.5, 1.0};

    cout << "P1 = " << P1 << " magnitude = " << P1.mag() << '\n';
    cout << "P2 = " << P2 << " magnitude = " << P2.mag() << '\n';
    cout << "P3 = " << P3 << " magnitude = " << P3.mag() << '\n';
    cout << "P4 = " << P4 << " magnitude = " << P4.mag() << '\n';

    for(int i=0; i<3; ++i)
        for(int j=0; j<3; ++j)
        {
            S[3*i+j] = (  P1*(1-u[i] ) +  P2*u[i] )*( 1 - v[j] ) +  (  P3*(1-u[i] ) +  P4*u[i] )* v[j];
            cout << "S[" << 3*i+j << "] = " << S[3*i+j] << " magnitude = " << S[3*i+j].mag() << '\n';
        }

    cout << endl;
    return 0;
}

The output is:

P1 = (2, 2, 2) magnitude = 3.4641
P2 = (7, 2, 2) magnitude = 7.54983
P3 = (3, 5, 6) magnitude = 8.3666
P4 = (8, 5, 6) magnitude = 11.1803
S[0] = (2, 2, 2) magnitude = 3.4641
S[1] = (2.5, 3.5, 4) magnitude = 5.87367
S[2] = (3, 5, 6) magnitude = 8.3666
S[3] = (4.5, 2, 2) magnitude = 5.31507
S[4] = (5, 3.5, 4) magnitude = 7.29726
S[5] = (5.5, 5, 6) magnitude = 9.55249
S[6] = (7, 2, 2) magnitude = 7.54983
S[7] = (7.5, 3.5, 4) magnitude = 9.19239
S[8] = (8, 5, 6) magnitude = 11.1803

Are the results correct?
Last edited on
Thank you very much I got the same answers using my code.

They way you code is advanced for me, if you don't mind can you explain to me the functions that you used. From line 10 to 20.

closed account (D80DSL3A)
Those are all operator overloads. It's a special syntax used to make functions which overload the usual operators in C++, to make them work with objects we define, like v3d objects.

The 1st on line 10 overloads the '*' operator for multiplication of a v3d by a scalar.
It enables us to write, for example;
v2 = v1*s; where v1, v2 are v3d's and s is a scalar.

The overload for '*' on line 14 makes it possible to evaluate scalar * v3d, or:
v2 = s*v1;

The overload for '+' on line 11 enables addition of v3d's:
v3 = v1 + v2;

The last one on lines 16-20 allows us to write a v3d to an output stream like cout, just as we can write the native types (int, float, etc.):
cout << v1; prints (v1.Y, v1.Y, v1.Z), as it's defined to on line 18.
It's required to return a reference to the ostream (cout in this case) to enable chaining of output.
ie, so this will work:
cout << v1 << ' ' << v2;
Operator overloading is a pretty cool feature of C++.
It enables us to manipulate user defined objects like native types.
Thank you very much for the explanation. Actually I had a problem with my answers, the magnitude of the vector outputs are wrong, for example :

Output is

S[0] = (2, 2, 2) magnitude = 2.934e-323
S[1] = (2.5, 3.5, 4) magnitude = 2.32e-328
S[2] = (3, 5, 6)
S[3] = (4.5, 2, 2) 
S[4] = (5, 3.5, 4) 
S[5] = (5.5, 5, 6) 
S[6] = (7, 2, 2)
S[7] = (7.5, 3.5, 4) 
S[8] = (8, 5, 6)


For all the vectors I get a magnitude in the same order.

My code:
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
struct v3d
{
	double X, Y, Z, mag;
};

//		Function to calculate dot product
double dotproduct(v3d a, v3d b)
{
	double val=0;
	
	val = a.X*b.X + a.Y*b.Y + a.Z*b.Z;

	return val;

}

// Function for directional vector
void d(v3d A, v3d B, v3d C, v3d &D, v3d &E)
{ 
D.X = B.X - A.X;
D.Y = B.Y - A.Y;
D.Z = B.Z - A.Z;

E.X = C.X - A.X;
E.Y = C.Y - A.Y;
E.Z = C.Z - A.Z;
}

//		Function to calcuate cross product
void crossproduct(v3d A, v3d B, v3d &C)
{
	C.X = A.Y * B.Z - A.Z * B.Y;
	C.Y = A.Z * B.X - A.X * B.Z;
	C.Z = A.X * B.Y - A.Y * B.X;
}

//		To calculate the magnitude of a vector
void magnitude(v3d &a)
{
	 a.mag = sqrt(dotproduct(a,a));
}

//		To create a normalised vector given two other vectors
void normalise (v3d &v, v3d a, v3d b)
{
	v3d temp;

	temp.X = b.X - a.X;
	temp.Y = b.Y - a.Y;
	temp.Z = b.Z - a.Z;
	magnitude(temp);

	v.X = temp.X/temp.mag;
	v.Y = temp.Y/temp.mag;
	v.Z = temp.Z/temp.mag;
	magnitude(v);

}

void pprint(v3d A)
{
     cout<<A.X<<"\t"<<A.Y<<"\t"<<A.Z<<"\t"<<A.mag<<"\n";
}


int main()
{

double P1x, P1y, P1z, P2x, P2y, P2z, P3x, P3y, P3z, P4x, P4y, P4z;


P1x = 2;
P1y = 2;
P1z = 2;

P2x = 7;
P2y = 2;
P2z = 2;

P3x = 3;
P3y = 5;
P3z = 6;

P4x = 8;
P4y = 5;
P4z = 6;

v3d P1, P2, P3, P4;

       P1.X = P1x;
       P1.Y = P1y;
       P1.Z = P1z;
       magnitude(P1);
       cout<<"P1\n";
       pprint(P1);

       P2.X = P2x;
       P2.Y = P2y;
       P2.Z = P2z;
       magnitude(P2);
       cout<<"P2\n";
       pprint(P2);
       
       P3.X = P3x;
       P3.Y = P3y;
       P3.Z = P3z;
       magnitude(P3);
       cout<<"P3\n";
       pprint(P3);

       P4.X = P4x;
       P4.Y = P4y;
       P4.Z = P4z;
       magnitude(P4);
       cout<<"P4\n";
       pprint(P4);

// assign values to u and v array
double u[3] = {0.0, 0.5, 1.0 }, v[3] = {0.0, 0.5, 1.0 };


// 3d vectors to output 9 vectors 
v3d S[9];

for(int i=0; i<3; ++i)
    for(int j=0; j<3; ++j)
    {
        S[3*i+j].X = (  P1.X*(1-u[i] ) +  P2.X*u[i] )*( 1 - v[j] ) +  (  P3.X*(1-u[i] ) +  P4.X*u[i] )* v[j];
        S[3*i+j].Y = (  P1.Y*(1-u[i] ) +  P2.Y*u[i] )*( 1 - v[j] ) +  (  P3.Y*(1-u[i] ) +  P4.Y*u[i] )* v[j];
        S[3*i+j].Z = (  P1.Z*(1-u[i] ) +  P2.Z*u[i] )*( 1 - v[j] ) +  (  P3.Z*(1-u[i] ) +  P4.Z*u[i] )* v[j];
	    pprint(S[3*i+j]);
}


Last edited on
closed account (D80DSL3A)
You should probably squeeze a call to magnitude(S[3*i+j]); in before line 131.
Last edited on
Thank you! I had another question as well. If you see the code below I have creation two functions to calculate the cross-product of two vectors and hence create a triangle with a orthogonal vector uhat, vhat and so on. There are eight triangles that can be formed with the vectors. I wanted to find out if there is a way that is much shorter to do cause as you can see from the code I am using individual functions to create triangles and its orthogonal vectors.

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
//		Definition of structure "v3d" AKA a vector
struct v3d
{
	double X, Y, Z, mag;
};

//		Function to calculate dot product
double dotproduct(v3d a, v3d b)
{
	double val=0;
	
	val = a.X*b.X + a.Y*b.Y + a.Z*b.Z;

	return val;

}

// Function for directional vector to create cross product
void d(v3d A, v3d B, v3d C, v3d &D, v3d &E)
{ 
D.X = B.X - A.X;
D.Y = B.Y - A.Y;
D.Z = B.Z - A.Z;

E.X = C.X - A.X;
E.Y = C.Y - A.Y;
E.Z = C.Z - A.Z;
}

//		Function to calcuate cross product
void crossproduct(v3d A, v3d B, v3d &C)
{
	C.X = A.Y * B.Z - A.Z * B.Y;
	C.Y = A.Z * B.X - A.X * B.Z;
	C.Z = A.X * B.Y - A.Y * B.X;
}

//		To calculate the magnitude of a vector
void magnitude(v3d &a)
{
	 a.mag = sqrt(dotproduct(a,a));
}

//		To create a normalised vector given two other vectors
void normalise (v3d &v, v3d a, v3d b)
{
	v3d temp;

	temp.X = b.X - a.X;
	temp.Y = b.Y - a.Y;
	temp.Z = b.Z - a.Z;
	magnitude(temp);

	v.X = temp.X/temp.mag;
	v.Y = temp.Y/temp.mag;
	v.Z = temp.Z/temp.mag;
	magnitude(v);

}

void pprint(v3d A)
{
     cout<<A.X<<"\t"<<A.Y<<"\t"<<A.Z<<"\t"<<A.mag<<"\n";
}


int main()
{

double P1x, P1y, P1z, P2x, P2y, P2z, P3x, P3y, P3z, P4x, P4y, P4z;


P1x = 2;
P1y = 2;
P1z = 2;

P2x = 7;
P2y = 2;
P2z = 2;

P3x = 3;
P3y = 5;
P3z = 6;

P4x = 8;
P4y = 5;
P4z = 6;

v3d P1, P2, P3, P4;

       P1.X = P1x;
       P1.Y = P1y;
       P1.Z = P1z;
       magnitude(P1);
       cout<<"P1\n";
       pprint(P1);

       P2.X = P2x;
       P2.Y = P2y;
       P2.Z = P2z;
       magnitude(P2);
       cout<<"P2\n";
       pprint(P2);
       
       P3.X = P3x;
       P3.Y = P3y;
       P3.Z = P3z;
       magnitude(P3);
       cout<<"P3\n";
       pprint(P3);

       P4.X = P4x;
       P4.Y = P4y;
       P4.Z = P4z;
       magnitude(P4);
       cout<<"P4\n";
       pprint(P4);
       

// assign values to u and v array
double u[3] = {0.0, 0.5, 1.0 }, v[3] = {0.0, 0.5, 1.0 };

v3d temp1, temp2, temp3, uhat;
v3d temp4, temp5, temp6, vhat;
v3d temp7, temp8, temp9, what;



// 3d vectors to output 9 vectors 
v3d S[9];

for(int i=0; i<3; ++i)
    for(int j=0; j<3; ++j)
    {
        S[3*i+j].X = (  P1.X*(1-u[i] ) +  P2.X*u[i] )*( 1 - v[j] ) +  (  P3.X*(1-u[i] ) +  P4.X*u[i] )* v[j];
        S[3*i+j].Y = (  P1.Y*(1-u[i] ) +  P2.Y*u[i] )*( 1 - v[j] ) +  (  P3.Y*(1-u[i] ) +  P4.Y*u[i] )* v[j];
        S[3*i+j].Z = (  P1.Z*(1-u[i] ) +  P2.Z*u[i] )*( 1 - v[j] ) +  (  P3.Z*(1-u[i] ) +  P4.Z*u[i] )* v[j];
	    magnitude(S[3*i+j]);
		pprint(S[3*i+j]);
}



d(S[0], S[3], S[1], temp1,temp2);
crossproduct (temp1,temp2, temp3);
magnitude(temp3);
       uhat.X = temp3.X / temp3.mag;
	   uhat.Y = temp3.Y / temp3.mag;
	   uhat.Z = temp3.Z / temp3.mag;
	   magnitude(uhat);
cout<<"uhat\n";
pprint(uhat);

d(S[3], S[4], S[1], temp4,temp5);
crossproduct (temp4,temp5, temp6);
magnitude(temp6);
       vhat.X = temp6.X / temp6.mag;
	   vhat.Y = temp6.Y / temp6.mag;
	   vhat.Z = temp6.Z / temp6.mag;
	   magnitude(vhat);
cout<<"vhat\n";
pprint(vhat);

d(S[3], S[6], S[4], temp7,temp8);
crossproduct (temp7,temp8, temp9);
magnitude(temp9);
       what.X = temp9.X / temp6.mag;
	   what.Y = temp9.Y / temp6.mag;
	   what.Z = temp9.Z / temp6.mag;
	   magnitude(what);
cout<<"what\n";
pprint(what);
Last edited on
closed account (D80DSL3A)
I'm afraid I don't understand your overall task, so I can't really see what functions to write to streamline the calcs.

I do see a couple of ways to simplify what I do see.
Focusing on making the code shorter for each case treated at the end, ie. blocks of code like lines 144-152. How to make that take < 10 lines of code?
Then, how to process these cases in a loop, instead of individually?
Is this what you mean?

For starters, any function which calcs a vectors components should also calc its magnitude.
eg. crossproduct() should call magnitude(). d() should calc the mags of the vectors D and E.

The normalize() seems odd. It is special purpose to subtract 2 vectors and produce a unit vector.
As such, it isn't useful for normalizing a single vector as you're doing eg. lines 147-150.
Write a normalize() which takes just one vector to normalize. Pass the vector b-a if that's what you want a normal to.

You're finding out why it's such an advantage to have a more fully featured v3d class. The more involved your vector operations, the more useful such a class becomes.

Finally, automating the calcs near the end can be done by using arrays of vectors instead of individually named ones. eg temp[8] to replace temp1, temp2,...
uhat[3] to replace uhat, vhat, what.
closed account (D80DSL3A)
I've looked more carefully at what's going on in eg lines 144-150.
With an appropriate v3d class, that would be:
1
2
uhat = (S[3]-S[0]).cross(S[1]-S[0]);
uhat *= 1/uhat.mag;


Heck, if the v3d class has a unit() function, which returns a unit length version of the calling vector, and we have an overload for operator<<, like in my earlier code, then all 9 lines of code become just 1 line:
cout << "uhat\n" << (S[3]-S[0]).cross(S[1]-S[0]).unit();

Do you see the utility yet?
Last edited on
Yes I do and I really need to get a hold of operator overloading. As you can see my programming is very basic! I am trying to reduce the code I will keep the update going if I have a questions.

Thank you once again
closed account (D80DSL3A)
You're welcome.
It took me several years to learn and become somewhat comfortable with operator overloading. You're doing quite well for a beginner!

This is why I also included suggestions for ways to improve things using your global function approach.
Hey ! I had a question actually, I am trying to write a code to find the inverse of a 3 by 3 matrix and I am having a bit of problem.

I am trying to write the the inverse of the matrix as a global function as I have several 3 by 3 matrices to inverse so I just call the function when I want to find the inverse of the matrix.

Any suggestions?
closed account (D80DSL3A)
What part are you having a problem with?

1) Method of calculation?
If so, I went with this pretty straightforward method:
http://www.mathsisfun.com/algebra/matrix-inverse-minors-cofactors-adjugate.html

2) Representing the matrix?
How did you choose to do this?
a) As a 3x3 array of doubles?
b) As a matrix structure similar to your v3d structure, containing a 3x3 array of doubles as a data member?

I needed to add an inverse method to my own m3d class, so I did that this morning after seeing your post here. I used the method outlined at the site linked above.
Thanks for the prompt!

As an exercise, I also did it using raw 3x3 arrays of doubles and a global inverse function, ie. 2a above.
Here's that result:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void display( double m[][3] )
{
    for(int i=0; i<3; ++i)
        cout << m[i][0] << ' ' << m[i][1] << ' ' << m[i][2] << '\n';
    cout << '\n';
}

void inverse( double m[][3], double inv[][3] )
{
   // apply your choice of calculation method here
}

int main()
{

    double a[3][3] = { {3,0,2}, {2,0,-2}, {0,1,1} };// a matrix to invert
    double aInv[3][3];// the inverted matrix to be
    display( a );
    inverse( a, aInv );// calculate inverse and store in aInv
    cout << endl;
    display( aInv );

    return 0;
}
Thank you for your reply, I am using actually trying to use the 2b method to represent my matrix as this is a continuation of my previous code and I need the elements of the v3d to invert.

Am trying one method out and I will post it, fingers crossed its works!
Hey ! good morning. I actually had questions regarding the code I was writing for the above problem.

So I had an attempt to writing a code, for calculating the inverse of a 3 by 3 matrix and am using the co factors method. The problem am facing is inputting this in a global function form (the void inverse part).

Secondly, if you run my code the answer is printed in a wrong way. Taking this matrix {(4,3,2) , (1,2,3,) , (6,5,3)} as an example, the printed output should be {(1.8,-2 ,-1) , (-3,0,2) , (1.4,0.4,1)}. But my printed output is stored in a column. If you run my code below you will see { 1.8
-2
-1}.


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
 #include<iostream>
#include<conio.h>
using namespace std;
int main()
{int a[3][3],i,j;
 
 float determinant=0;

 cout<<"Find Inverse Of Matrix\n";
 cout<<"Enter elements of 3x3 matrix:\n";
 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   cin>>a[i][j];
  }
 }
 cout<<"\nThe entered matrix is:\n";
 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   cout<<a[i][j]<<"  ";
  }
  cout<<"\n";
 }
 for(i=0;i<3;i++)
 {
  determinant = determinant + (a[0][i]*(a[1][(i+1)%3]* a[2][(i+2)%3] - a[1][(i+2)%3]*a[2][(i+1)%3]));
 }
 if(determinant==0)
 {
  cout<<"Inverse does not exist (Determinant=0).\n";
 }
 else
 {
  cout<<"\nInverse of matrix is: \n";
 }
 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   cout<<((a[(i+1)%3][(j+1)%3] * a[(i+2)%3][(j+2)%3]) - (a[(i+1)%3][(j+2)%3]*a[(i+2)%3][(j+1)%3])) / determinant <<"\t";
  }
  cout<<"\n";
  }

}
Last edited on
Pages: 12