Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
#include <iostream>
#include <math.h>
#include "boost/math/constants/constants.hpp"
const double pi = boost::math::constants::pi<double>();
int main() {
double x = 2;
double y = 1;
double angle = 90; //in degrees
double rad { angle * pi / 180 }; //converting to rads
std::cout << "rad: " << rad << std::endl; //1.5708 - OK
double c = cos( rad );
std::cout << "cos(rad): " << c << std::endl; //6.12303e-017 - Huh? Should be ~ -3.2051033e-9
double s = sin( rad );
std::cout << "sin(rad): " << s << std::endl; //1 - OK
x = x * c - y * s;
y = x * s + y * c;
std::cout << "(" << x << "," << y << ")" << std::endl;
return 0;
}
So this is weird, I'm trying to do a rotation but the cos is giving me the wrong value. It should be something near to -3.2051033e-9 but I end up with 6.12303e-017. I've converted my angle to radians and it checks out. sin( rad ) returns the correct value as well.
What gives?
Edit:
The code has an error but not related to the question. On y = x * s + y * c; the x should refer to the the value declared at the top but as the previous equation overrides that value the y at the end would be wrong.
Thanks for the clarification of exponents. I got a bit confused.
cos(90) (degrees) is approximately zero, as in 0.0. Worrying about getting a number back that is e-17 vs e-9 is not meaningful, they are both basically zero.
How close it the result actually is depends on how they represented pi, 90.0, 180.0, and the implementation of the cos function in math.h.
It should be something near to -3.2051033e-9 but I end up with 6.12303e-017.
I don't know why you think it "should be -3.2051033e-9" because cos(90º) is zero, and -0.0000000032051033 is well outside of the margin of error of your calculations,
The value you're getting, 0.0000000000000000612303 is zero, and therefore correct, within the margin of error of your calculations.
There is no error in your code..
In the cos function (cos ), return value is a real. And here is some examples;
(cos -1) returns 0.540302
(cos 0.0) returns 1.0
(cos (* pi 0.5)) returns 6.12303e-017 which is practically equal to **0**
And also you can check it with inverse cos with cos(6.12303e-017) and you will see it is 90 degree
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
R (in feet) = (velocity (in ft/s))^2 / g (which is 9.8 m/s^2) * sin(2theta).
I checked various inputs using websites like this one https://www.ajdesigner.com/phpprojectilemotion/range_equation.php#ajscroll to check if my code was giving the right answer but it isn't and I don't know why. Any simple solutions?? Here it is below:
#include <iostream>
#include <cmath>
using namespace std;
const double GRAVITY_MPS = 9.8;
const double METERS = 3.28084;
int main() {
double v = 0.0, degrees = 0.0;
cout << "Enter the velocity (mi/hr) and cannon angle (degrees): \n";
cin >> v >> degrees;
double v2 = 0.0;
v2 = v * 5280.0 / 3600.0;
double radians = degrees * M_PI / 180.0;
double r = (pow(v2,2.0) / GRAVITY_MPS) * sin((2.0 * radians));
double r2 = r * METERS;
cout << "Yikes travels " << r2 << " feet.";
return 0;
}
The value of r has units (ft/s)2 / (m/s2) == (ft2/s2) / (m/s2) == ft2 / m. Then r2 has units ft2/m * ft/m resulting in units of ft3 / m2.
You want the inverse of the multiplication factor for r2, i.e. m/ft:
double r2 = r * 0.3048; // meters / foot
Your v0 can't be in feet cause gravity is in meters.
Change 5280.0 to 1609.3 (mi to m) and it works.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
The problem states that given the radius of three circles, and assuming that three circles touch themselves in a way shown:
we need to find out the area of the blue portion between them. I have written the following code and run a few test cases. All of them worked fine. The online judge says the answer is wrong.
#include <iostream>
#include <math.h>
#include <iomanip>
using namespace std;
int main()
{
double r1, r2, r3, tarea, r1area, r2area, r3area;
long double res;
int i, test;
cin >> test;
for(i = 1;i <= test;i++)
{
cin >> r1 >> r2 >> r3;
tarea = sqrt(((r1 + r2 + r3)*r1*r2*r3));
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
r3area = 0.5*(r3*r3)*(asin((2*tarea)/((r1+r2)*(r2+r3))));
res = tarea - (r1area + r2area + r3area);
cout << "Case " << i << ": " << fixed << setprecision(8) << res << endl;
}
return 0;
}
The lack of simmetry in the formula is a strong evidence that something is wrong in the posted code, as shown in idclev 463035818's answer.
There's another mathematical issue, though, that may come up in the tests.
The code tries to implement the law of sines, in order to calculate the angles of the triangle formed by the centers of the circles. The problem is that when one of the radii is small enough, the corresponding angle in the triangle become obtuse and the chosen formula doesn't hold anymore.
Consider the documentation of std::asin, the returned value is in the range [-π/2, π/2], it can't represent an obtuse angle.
We could rewrite the formulas using the law of cosines (which doesn't have this issue) or we could just evaluate the greatest angle remembering that the three interior angles of a triangle add up to π.
#include <cmath>
#if __has_include(<numbers>)
# include <numbers>
#else
namespace std::numbers {
inline constexpr double pi = 3.14159265358979323846;
}
#endif
double area_circumscribed_by_circles(double r1, double r2, double r3)
{
// I want the third to have the smaller radius.
if (r1 < r2) {
if ( r1 < r3 )
std::swap(r1, r3);
} else {
if ( r2 < r3 )
std::swap(r2, r3);
}
if (r3 == 0.0)
return 0.0;
// Apply Heron's formula to find the area of the triangle
// formed by the centers of the circles.
double area = std::sqrt((r1 + r2 + r3) * r1 * r2 * r3);
// Find the first two angles using the law of sines.
double angle_1 = std::asin(2.0 * area / ((r1 + r2) * (r1 + r3)));
double angle_2 = std::asin(2.0 * area / ((r2 + r1) * (r2 + r3)));
// The third angle may be obtuse, we can't use the previous formula.
double angle_3 = std::numbers::pi - (angle_1 + angle_2);
// Now we can subtract the area of the sectors.
return area - 0.5 * (r1 * r1 * angle_1 + r2 * r2 * angle_2 + r3 * r3 * angle_3);
}
Look closely at the formulas:
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
r3area = 0.5*(r3*r3)*(asin((2*tarea)/((r1+r2)*(r2+r3))));
res = tarea - (r1area + r2area + r3area);
Without entering into the details of the maths I know that they cannot be correct. Why? Symmetry! The final result does not change if you permute the labeling of the circles. This is fine for the last line, because with
auto a = r1area;
auto b = r2area;
auto c = r3area;
all those expressions yield the same result:
res = tarea - (a + b + c);
res = tarea - (a + c + b);
res = tarea - (b + a + c);
res = tarea - (b + c + a);
....
Similarly you should get the same result for permutations of r1,r2 and r3 and this is not the case.
This
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
can be rewritten as
r1area = calc_area( r1*r1, r1+r2, r1+r3);
or
Aarea = calc_area( A*A, A+B, A+C);
Because of the symmetry of the problem, it should be possible to get the forumla for Barea by permuting A,B and C, but if we swap A and B (those are just labels!) then we get
Barea = calc_area( B*B, B+A, B+C);
while you have:
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
// ->
r2area = calc_area( r2*r2, r2+r3, r1+r3);
// ->
Barea = calc_area( B*B, B+C, A+C);
Note that the last parameter is B+C vs A+C, ie XArea has X+Y,X+Z in one case but X+Y,Y+Z in the other. Hence no permutation of the labels can make those formulas the same. However, the area between the circles will not change if you put different labels on the circles, ergo your formulas cannot be correct.
Using a + i b = sqrt(a*a + b*b) * exp(i arctan2(a,b)) I arrive at the following way to compute complex roots. However, I heard that trigonometric functions rather use up performance so I wonder if there is a better way in vanilla c++ (no external libaries).
Example: Let u+iv = sqrt(a+i b)
#include <math.h>
#include <iostream>
int main(){
double a = -1.;
double b = 0;
double r = sqrt(sqrt(a*a+b*b));
double phi = 0.5 * atan2(b, a);
double u = r * cos(phi);
double v = r * sin(phi);
std::cout << u << std::endl;
std::cout << v << "i" << std::endl;
}
This is just meant as a MWE, so it's not written in a class or method.
Yes there is! I'm going to link a good explanation of the process here, but it looks like this can be accomplished by only calculating the magnitude of the original number and subtracting out the real portion of the original number and finally taking the square root of that to find the imaginary part of the square root. The real part can be found by dividing the imaginary part of the original number by 2 * the imaginary part of the root to get your final answer.
https://www.qc.edu.hk/math/Advanced%20Level/Finding%20the%20square%20root%20of%20a%20complex%20number.htm
Let me know if you need more help with the code but this requires no trig functions.
Write a program that determines how far and for how long a time a rock will travel when you throw it off a cliff. Click here to copy the file toss.txt to your desktop (right click the file name and choose Save as). The file contains the height of the cliff in meters.
The program will then:
Open the file toss.txt and read the cliff height into a double-precision variable, then echo print the value of the cliff height to the screen with an appropriate label.
Ask the user for the angle at which the rock is thrown (90 degrees is straight up, and 0 degrees is straight forward), and the velocity at which the rock is thrown (in miles per hour).
Check to make sure the angle is greater than or equal to 0 and less than or equal to 90. If it is not, the program terminates and prints an appropriate error message to the screen.
Check to make sure the velocity is less than or equal to 100 mph and greater than or equal to 0 mph. If it is not, the program terminates and prints an appropriate error message to the screen.
If the angle and velocity are valid, the program completes the calculations as follows:
Converts miles per hour to meters per second.
Converts the angle to radians.
Calculates the time traveled using the following equations:
where
Calculates the distance traveled in the horizontal direction using:
Outputs the time and distance traveled in the horizontal direction to the screen with appropriate labels.
Prints an appropriate message telling the user if the distance traveled in the horizontal direction was greater than, less than, or equal to the height of the cliff.
/* This program */
using namespace std;
#include<iostream>
#include<cmath>
#include<iomanip>
#include<fstream>
int readit ();
int calcit (double, double, double);
int main()
{
readit ();
system ("pause");
return 0;
}
int readit ()
{
double hite, angl, v;
ifstream datain ( "toss.txt" );
datain >> hite;
cout << "The cliff height is " << hite << " meters"<< endl;
cout << "Enter the angle in degrees (from horizontal) the rock is thrown: "
<< endl;
cin >> angl;
if (angl>=0 && angl<=90)
{
cout << endl << "The angle you have entered is "<<angl<< endl <<endl;
}
else
{
cout << "The angle you have entered is not acceptable" << endl;
return 0;
}
cout << "Enter the velocity in mph the rock is thrown: " << endl;
cin >> v;
if (v>=0 && v<=100)
{
cout << endl << "The velocity at which the rock is thrown is "<<v<<
" mph" << endl << endl;
}
else
{
cout << "The velocity you have entered is not acceptable" << endl;
return 0;
}
calcit (hite, angl, v);
}
int calcit (double hite, double angl, double v)
{
double tyme, dist;
v = v * (1609.344/3600);
angl = angl*(M_PI/180);
tyme = -v*sin(angl) + (sqrt((v*sin(angl)*v*sin(angl)) + 2*9.8*hite)/9.8) + (2*(v*sin(angl))/9.8);
dist = (tyme * v) * cos(angl);
cout << tyme << " " << dist <<endl;
}
I am trying to get the correct time the rock is traveling before it hits the ground but i keep getting incorrect answers. I am not sure if i am turning the equation to figure out the time the rock will be in the air until impact into c++ language right. any have any ideas??? i really need to finish this damn project.
Starting from the equation for the y (height above 0) for the rock we have
y = h + v*sin(a)*t - g/2*t^2
which transforms into
g/2 T^2 - v*sin(a)*T - h == 0
when we solve for the final condition y(T)=0.
This yields
T = v*sin(a)/g + sqrt(v*sin(a)*v*sin(a) + 2*g*h)/g
I just can't figure out where the first part -v*sin(angl) in your equation comes from. Everything else looks just fine. So it seems not to be with your code but with the equation you started.
The equation you want is:
s =ut + 1/2 at^2
s = Total distance traveled. (Height of the cliff)
u = Starting velocity (In your case negative as you are throwing
away from the target. And take into account
that not all the starting velocity is away
from the target (eg angle 0 mean u = 0))
a = acceleration (9.81 m/s2)
t = time (The value you want to calculate).
Rearrange the formula to solve for t
To find the solution for t where s = 0...
This formula is you basic quadratic:
y = a.x^2 + b.x + c
Where:
x/y are variables.
a/b/c are constants.
The solution for a quadratic equation where y is 0 is:
x = [ -b ± sqrt(b^2 - 4ac) ] / 2a
Notice the ± symbol. There are actually two solutions to the problem.
You should be able to deduce which one is correct for you as the other
is probably negative.
In your particular case the map is:
x ==> t
y ==> 0
a ==> 1/2.g
b ==> u
c ==> -s
I would suggest a few things to "clean up" the code a bit:
If functions return int ensure that they do really return something. (main doesn't have to but other functions do).
Calculate v * sin(ang1) once then use it in your formula thereafter. Not only more efficient but will make your code clearer.
Like you have given Pi a "constant", do that with other numbers you are using like 9.8 (gravitational force?)
If you have a confusing formula in the code, just introduce more variable names until the meaning becomes obvious. So long as you don't reassign different values to the same variables, this will not make the program confusing.
int calcit (double hite_meters, double angl_deg, double v_mph)
{
double const gravity = 9.8;
double v_ms = v_mph * (1609.344/3600);
double angl_rad = angl_deg * (M_PI/180);
double v_vertical = v_ms * sin( angl_rad );
double time_up = v_vertical / gravity; // [m/s] / [m/s^2] = [s]
double time_down_over_cliff = time_up;
// use quadratic formula t = ( -v - ( v^2 - 4gd )^1/2 ) / 2g:
double time_under_cliff = ( - v_vertical
- sqrt( ( v_vertical * v_vertical )
- ( 4 * - gravity * hite_meters ) ) // negative gravity = down
) / ( 2 * - gravity ); // ( [m/s] + ([m/s]^2 - [m/s^2]*[m])^1/2 ) / [m/s^2]
// = [m/s] / [m/s^2] = [s]
double time_total = time_up + time_down_over_cliff + time_under_cliff;
double v_horizontal = v_ms * cos( angl_rad );
double dist_horizontal = v_ms * time_total;
cout << time_total << " " << dist_horizontal <<endl;
}
Every line of code produces a new, relevant piece of information. When converting to a new unit, I introduce a new variable with a new name. Formulas involving more than one unit get the unit types explained in a comment. This should help turn up unit conversion errors which otherwise I can't help you catch.
Writing this kind of code involves more typing, but the time saved on head-scratching and asking for help more than makes up for it.
The program itself is not any less efficient. More importantly, it may be easily modified, so it won't turn into an inefficient mess after a few revisions.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
My code is producing an output of nan.
I have looked around and I'm guessing it is as the equation is complicated from what I gather C++ doesn't recieve complicated equations too well.
But that doesnt seem right.
Here's my code:
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
int Backfill;
double SlopeAngleOfWall, AngleOfInternalFriction, AngleOfFrictionSoilAndWall, BackfillSlope, CoefficientOfActivePressure;
cout << "Retaining Wall Calculator \n";
cout << "Enter the slope angle of the wall, this is measured from the horizontal plane, therefor will be 90 degrees if the retaining wall is vertical \n";
cin >> SlopeAngleOfWall;
cout << "Enter the angle of internal friction \n";
cin >> AngleOfInternalFriction;
cout << "Enter the angle of friction between the soil and the wall \n";
cin >> AngleOfFrictionSoilAndWall;
cout << "Enter the angle of the backfill slope \n";
cin >> BackfillSlope;
/* To make sin function work is is typed (angle*pi/180) */
/* To make sin square work is is typesd (pow(sin (angle*pi/180), 2.0) */
/* To add a square root sqrt is used */
CoefficientOfActivePressure = (pow (sin ((SlopeAngleOfWall + AngleOfInternalFriction)*pi/180), 2.0)) / ((pow (sin (SlopeAngleOfWall*pi/180), 2.0) * sin ((SlopeAngleOfWall * AngleOfFrictionSoilAndWall) * pi / 180)) *( 1 + sqrt( ( sin ((AngleOfInternalFriction + AngleOfFrictionSoilAndWall) * pi / 180) * sin ( (AngleOfInternalFriction - BackfillSlope) * pi / 180) / sin ( (SlopeAngleOfWall - AngleOfFrictionSoilAndWall) * pi / 180 ) * sin ( (SlopeAngleOfWall + BackfillSlope) * pi / 180)))));
cout << "The coefficient of active pressure acting on the wall is" << CoefficientOfActivePressure <<"\n"
}
It looks like you are trying to implement Coulomb's Theory of Lateral earth pressure. The formula looks like this:
(From http://www.soilmanagementindia.com)
Assuming that your implementation is correct, the only way to get NaN as result is if the square-root argument is negative.
The bottom line is that the equation is not valid for all possible combinations of input, and for the wrong set of input an output of NaN is to be expected.