What is wrong with my equation or conversions? [closed] - c++

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.

Related

What is wrong with this code as the answer to the following online judge problem? [closed]

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.

rotating a vector using parametric equation of 3d circle [closed]

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 6 years ago.
Improve this question
I'm not getting the required output i.e x2,y2,z2 in below code. Here the angle t is in degree, (x2,y2,z2) is the pint of vector face after being rotated and (a2,b2,c2) is the direction cosine of the rotated vector.I used rviz to visualize the rotating vector but its not comming as thought i.e its not rotating.
double xgp[ipgp] = 23, ygp[ipgp] = 45, zgp[ipgp] = 345; int ipgp = 0;
double a2, b2 , c2, a1, b1, c1 = ...
double la = 0.0032;
for(double t=0;t<360;t+=la)
{
double x2 = xgp[ipgp]+a2*cos(t)+a1*sin(t);
double y2 = ygp[ipgp]+b2*cos(t)+b1*sin(t);
double z2 = zgp[ipgp]+c2*cos(t)+c1*sin(t);
a2 = x2-xgp[ipgp]; // vector (xgp,ygp,zgp)->(x2,y2,z2)
b2 = y2-ygp[ipgp];
c2 = z2-zgp[ipgp];
int i = round(sqrt(pow(a2,2)+pow(b2,2)+pow(c2,2)));
std::cout<<i<<std::endl;
}
There are two issues with the code that you posted:
You did not specify how (a1,b1,c1) and (a2,b2,c2) are set. These need to be:
orthogonal to (xgp,ygp,zgp)
orthogonal to each other
unit vectors
In the loop, you reset (a2,b2,c2) to be the rotated unit vector. You can't do that and still maintain orthogonality between (a1,b1,c1) and (a2,b2,c2) for the next step of the loop. This is probably the main reason why your print out of i is not all 1's
The following code does what you intend
#include <iostream>
#include <math.h>
int main() {
double xgp = 23., ygp = 45., zgp = 345.;
// setting (a2,b2,c2) to be orthogonal to (xgp,ygp,zgp) with unit magnitude
double a2 = -45./sqrt(23.*23. + 45.*45.);
double b2 = 23./sqrt(23.*23. + 45.*45.);
double c2 = 0.;
// setting (a1,b1,c1) to be orthogonal to both (a2,b2,c2) and (xgp,ygp,zgp)
// using cross product (xgp,ygp,zgp) X (a2,b2,c2) with unit magnitude
double a1 = -23.*345./sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double b1 = -45.*345./sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double c1 = (23.*23. + 45.*45.)/sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double la = 0.0032;
for(double t=0;t<360;t+=la) {
double x2 = xgp+a2*cos(t)+a1*sin(t);
double y2 = ygp+b2*cos(t)+b1*sin(t);
double z2 = zgp+c2*cos(t)+c1*sin(t);
// cannot overwrite a2, b2, c2; otherwise (a2,b2,c2) is no longer orthogonal to (a1,b1,c1)!
double a3 = x2-xgp; // vector (xgp,ygp,zgp)->(x2,y2,z2)
double b3 = y2-ygp;
double c3 = z2-zgp;
// (a3,b3,c3) is a unit vector!
int i = round(sqrt(pow(a3,2)+pow(b3,2)+pow(c3,2)));
std::cout<<i<<std::endl;
}
return(0)
}
Note that rotating in units of degrees or radians does not matter in terms of your question. However, you should follow #Bob 's advice and make sure you know yourself what units you are intending.
Hope this helps.

cos giving out the wrong value [closed]

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

Averaging circular values (particularly Hues in HSL color scheme)

So I was trying to puzzle out how to calculate the average hue of a number of objects whose colors are represented by HSL values. Thankfully, I stumbled across this Stack Overflow post, and set to work implementing the algorithm provided in the top answer (I am working in C++).
Unfortunately, my implementation doesn't seem to work. Here it is, in full; note that though I write "Hue" I am using angles, in degrees, as per the initial implementation (switching from 0-360 angles to 0-256 hues, once I know my code works, shouldn't be hard).
#include <iostream>
#include <vector>
#include <cmath>
#define PI (4*atan(1))
int main()
{
///
/// Calculations adapted from this source:
/// https://stackoverflow.com/questions/8169654/how-to-calculate-mean-and-standard-deviation-for-hue-values-from-0-to-360
std::vector<double> Hues = {355, 5, 5, 5, 5};
//These will be used to store the sum of the angles
double X = 0.0;
double Y = 0.0;
//Loop through all H values
for (int hue = 0; hue < Hues.size(); ++hue)
{
//Add the X and Y values to the sum X and Y
X += cos(Hues[hue] / 180 * PI);
Y += sin(Hues[hue] / 180 * PI);
}
//Now average the X and Y values
X /= Hues.size();
Y /= Hues.size();
//Get atan2 of those
double AverageColor = atan2(X, Y) * 180 / PI;
std::cout << "Average: " << AverageColor << "\n";
return 0;
}
Instead of the expected answer of 3 (since 355 should be equivalent to -5 in this scheme), I get 86.9951.
Can somebody point out what I'm doing wrong? This seems very basic.
atan2 takes its arguments in reverse order. I know, annoying! So try:
double AverageColor = atan2(Y, X) * 180 / PI;
The answer it gives now is 3.00488.
Try atan2(Y, X). atan2(a,b) is similar to atan(a/b), and you need the arctangent of the average sine over the average cosine.

Why is my code producing an output of nan? [closed]

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.