How to make this function...

Hi..

I need to calculate the 3 angles of a triangle using 1 function.
How do I manipulate the function to do that?

Angle A = arcos((b*b+c*c-a*a)/(2*b*c))
Angle B = arcos((a*a+c*c-b*b)/(2*a*c))
Angle C = arcos((a*a+b*b-c*c)/(2*a*b))

Here is the beginning of my function

1
2
3
  double angleofsides(double a, double b, double c)
double angle = arcos((a*a+b*b-c*c)/(2*a*b)
return angle;


How can the orders of a,b,c be changed or manipulated?

Thanks.
Last edited on
closed account (48T7M4Gy)
You could use a function which generalizes the problem. ie you send the function the sides in the order you want and get back the angle. By using a function you only have to write the equation once.
closed account (48T7M4Gy)
It's the same as what wizebin said about functions for your other problem. :)

http://www.cplusplus.com/forum/beginner/177612/
Thanks..
I have read that tutorial several times and it has helped.


If the sides are being passed in by a .dat file, how can I change the order in which the sides are being sent to the function?
closed account (48T7M4Gy)
a function doesn't require a .dat file. You are getting a bit lost I think.

Let's say you want to add up three numbers. You can do it the hard way and write the equation multiple times but if you design a function you can do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int functionAdd( int x, int y, int z)
{
    return x + y + z;
}

int main()
{
    int answer = 0;
    
    answer = functionAdd( 1, 2, 3);
    std::cout << answer << std::endl;
    
    answer = functionAdd( 4, 5, 6);
    std::cout << answer << std::endl;
}


6
15
 
Exit code: 0 (normal program termination)
Last edited on
Thanks for the help kemort.


I should have been more specific in my request for help.


Here is the complete assignment...
I'm just starting, but I think i'm okay on everything except what I asked about the angle function.


Write a complete program to calculate and output the perimeter, the area, the angles of a triangle in degrees, the sum of the three angles in degrees, the radius of the inscribed circle, the radius of the circumscribed circle, and the positive difference in radii using a suitable format to a text file called "triangles.txt" for each calculated value by inputting lower_a, upper_a, step_a, b, c from the data file "triangle.dat" (in Sakai assignment) with a loop for only 'a' which runs from the lower value to the upper value inclusive using the step value (you will test the step to make sure it is positive and make it positive if it isn't - you will output a statement that you are changing the step to make it positive) and an if statement to catch non-triangles (I suggest you look at the area calculation) and output a statement about having a non-triangle for these three sides or output these results for valid ones: perimeter and area with 4 decimal places, all angles with 1 decimal place, and the radii with 5 decimal places using either <iomanip> or <fstream> functions for formatting. In addition, you will have one function to convert radians to degrees, one function to calculate the angle from the sides, and any additional functions to make this program easier to write.
Writing 3 functions to calculate the 3 angles from the 3 sides will cost you ALL credit for this part of the assignment - changing the order of the sides in one function is all that is necessary!
Last edited on
closed account (48T7M4Gy)
Writing 3 functions to calculate the 3 angles from the 3 sides will cost you ALL credit for this part of the assignment - changing the order of the sides in one function is all that is necessary!


Given what I wrote I wouldn't blame the lecturer for being so tough.

Relating it back to your original function and what wizebin has suggested all you have to do is model that part of the exercise in the same way that functionAdd operates.

I think your use of a,b and c everywhere should be reviewed. Call them x,y and z in the function and then you'll see that a,b, and c can be passed to
angleofsides(double x, double y, double z) in any order you need to get the answers returned for the relevant angle you require.
Last edited on
Thanks. I'll keep thinking about it
closed account (48T7M4Gy)
1
2
3
4
5
double angleofsides(double x, double y, double z)
{
    double angle = arcos((x*x+y*y-z*z)/(2*x*y)
    return angle;
}


So in main() for instance:

1
2
3
double angle1 = angleofsides(a, b, c);
double angle2 = angleofsides(b, c, a);
double angle3 = angleofsides(c, a, b);


You can check this by
angle1 + angle2 + angle3 = PI radians ( = 180 degrees )






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <math.h>

double angleofsides(double x, double y, double z)
{
    double angle = acos( ( x * x + y * y - z * z ) / ( 2 * x * y ) );
    return angle;
}

int main()
{
    double a = 5, b = 6, c = 7;
    
    double angle1 = angleofsides( a, b, c);
    double angle2 = angleofsides( b, c, a);
    double angle3 = angleofsides( c, a, b);
    
    std::cout << angle1 + angle2 + angle3;
}

3.14159 
Exit code: 0 (normal program termination)

That was lucky :)
Last edited on
closed account (48T7M4Gy)
PS Note also it's acos not arcos in the C++ context - another small challenge.
Thanks kemort.

I'm going to have to play with that when it starts reading lines from the .dat file.
But I generally get it better now.


Here is the contents of triangle.dat
1.0 5.0 0.5 3.0 4.0
0.0 10.0 0.1 3.0 4.0
10.0 20.0 -1.0 13.0 4.0


I thought I was going to be able to read this in okay and increment as needed, but now I can't figure that out.

Each row is as follows
LowersideA, UppersideA, increment, SideB, SideC

I have tried to get this to work by calculating the perimeter with a for and while loop.... to no avail

It needs to calculate using LowersideA through UppersideA using the increment... so for row 1 that would be 10 triangles total.

Here's what I have...

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
include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

const double pi = 4.0 * atan(1.0);

double angleofsides(double x, double y, double z)
{
    double angle = acos((x*x+y*y-z*z)/(2*x*y));
    return angle;
}

double radtoDeg (double rad)
{
	double degree = ((rad * 180) / pi);
	return degree;
}


int main ()
{
ofstream fout ("triangles.txt");
ifstream infile;
infile.open("triangle.dat");

double LowsideA,UpsideA,sideB,sideC;
double step,n,k;

infile >> LowsideA >> UpsideA >> step >> sideB >> sideC;

//double sideA = UpsideA - LowsideA;

for (sideA=LowsideA; sideA <= UpsideA; sideA+=step)
{
double perimeter = sideA + sideB + sideC;
cout << perimeter;
}


//system ("pause");
return 0;
}


Last edited on
closed account (48T7M4Gy)
You're on the right track but what I suggest as your first step is just to read the .dat file in and print out the variables instead of jumping in and doing calculations.

Use the demo program from the file input/output tutorial on this site (top left hand menu). The demo includes a while loop to read all the data.
http://www.cplusplus.com/doc/tutorial/files/

This is the starting point which needs to be modified to suit your data structure:

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
// reading a text file
#include <iostream>
#include <fstream>
#include <math.h>

using std::endl;
using std::cout;
using std::ifstream;

double perimeter( double, double, double );
double angleofsides(double, double, double);

const double RAD_TO_DEG = 180 / ( atan(1) * 4 );

int main()
{	
	double LowersideA = 0, UppersideA = 0, step = 0, SideB = 0, SideC = 0;

	ifstream myfile("triangle.dat");

	if (myfile.is_open())
	{
		while ( myfile >> LowersideA >> UppersideA >> step >> SideB >> SideC )
		{
			// DISPLAY A HEADING
			cout << endl;
			cout << LowersideA << '\t' << UppersideA << '\t' << step << '\t' << SideB << '\t' << SideC << endl;

			// MAKE SURE step IS POSITIVE
			if (step < 0)
				step *= -1;
			
			// PROCESS THE INPUT
			for ( double SideA = LowersideA; SideA <= UppersideA; SideA += step )
				cout 
				<< SideA << '\t' << SideB << '\t' << SideC 
				<< '\t' << " p = " << perimeter( SideA, SideB, SideC ) 
				<<  '\t' << " a1 = " << angleofsides( SideA, SideB, SideC ) * RAD_TO_DEG << endl;

			cout << endl;

		}
		myfile.close();
	}

	else cout << "Unable to open file";

      return 0;
}

double perimeter(double x, double y, double z)
{
	return x + y + z;
}

double angleofsides(double x, double y, double z)
{
	return acos((x * x + y * y - z * z) / (2 * x * y));
}
Last edited on
Thanks a lot kemort.

It is going to take several hours to digest what you did.

So, lines 10 and 11 are function prototyping, correct?

closed account (48T7M4Gy)
No problem. There's lots more but I'll leave it to you to get back if you get stuck. It takes a little while but better if you try it yourself.

So, lines 10 and 11 are function prototyping, correct?

That's right lines 10 and 11 are the prototypes. You'll notice you don't normally include variable names until you get to the implementation part which normally goes after main() so that once they are working you don't have to wade through them.

You'll get some weird-looking answers ( like 'nan' etc) in some cases and that's because the 3 sides don't make a triangle. Hint: 'triangle inequality' might be a useful term to google.

Cheers

:)

Topic archived. No new replies allowed.