Calculate point/coordinate from distance and bearing - c#

Maths is not my strong suit and I think I have something mixed up here but I cannot figure out what.
I'm just trying to populate 2 new coordinates given a number of variables and constants.
if I make Origin coordinate 5,5 and Destination coordinate 10,5, I can work out that distance =5 and that the bearing from Origin to Destination is 90 using these two functions:
private static double GetDistance(PointF point1, PointF point2)
{
double a = (double)(point2.X - point1.X);
double b = (double)(point2.Y - point1.Y);
return Math.Sqrt(a * a + b * b);
}
public static double GetBearing(PointF coord1, PointF coord2)
{
double result = 0.0;
result = Math.Atan2(coord2.X - coord1.X, coord2.Y - coord1.Y) * (180 / Math.PI); //- Math.Atan2(coord4.y - coord3.y, coord4.x - coord3.x))
if (result < 0)
{
result = result + 360;
}
return result;
}
What I want to be able to do given an offset Distance of xd=1 and an offset bearing of 180(ie directly opposite direction to the destination) is plot the location 4,5. I'd also like to be able to feed a different offset bearing in of say 90 and plot 5,6.
Here's what I've tried but I get completely nonsensical values.
public static PointF CalculateCoordinate(double Angle, double Distance)
{
PointF coord = new PointF(Convert.ToSingle(Distance * Math.Cos(Angle)), Convert.ToSingle(Distance * Math.Sin(Angle)));
return coord;
}
and CalculateCoordinate(GetBearing(Destination, Origin),1) to reverse the bearing directly 180. I've tried this CalculateCoordinate(90,1) to calculate an offset to the side but that's not working either.
Where have I gone wrong, I'm sure it's something pretty stupid and simple.

There's two mistakes that I can see. First, Atan2 takes the Y value for the first parameter and the X value for the second:
Math.Atan2(coord2.Y - coord1.Y, coord2.X - coord1.X) * (180 / Math.PI);
Secondly, you're converting from radians to degrees in GetBearing, but you're not converting Angle from degrees to radians inside CalculateCoordinate e.g:
Math.Cos(Angle * (Math.PI / 180))

Related

How can I find a circle angle from x and y axis

Feel free to mark my question duplicated. Because I know absolute nothing about COS, SIN, and TAN and someone else probably already ask this question.
So, I was try to set the circular progress bar based on x and y axis that can get from gamepad input. The progress bar put it simple is just a Minimum of 0 and maximum of 360.
I did try to search a bit, but my best understanding is that it work with only 180 degree and positive x and y. But the input I get from the controller is and y from -1 to 1 (where x -1 is left and 1 is right, y -1 is bottom and 1 is top)
Here is my code so far.
var controller = Windows.Gaming.Input.Gamepad.Gamepads[0].GetCurrentReading();
x = controller.LeftThumbstickX
y = controller.LeftThumbstickY
//what do I have to do from here?
progress.Value = angle; //?
The trigonometric function atan2 is the tool for this job. In C#, this is implemented by Math.Atan2 :
double angleInRadians = Math.Atan2(y, x);
double angleInDegrees = (180 / Math.PI) * angleInRadians;
Using this formula with (for instance) parameters (1,1), you'll get a result of 45.
However, in terms of polar alignment, this angle measures anti-clockwise from "east". To convert this to an angle that measures clockwise from "north":
double compassRadians = Math.PI / 2 - angleInRadians;
double compassDegrees = (180 / Math.PI) * compassRadians;
but now we may encounter negative values, so we can normalize them with the following method:
double normalizeDegrees(double a) => ((a % 360) + 360) % 360; //convert to 0-360
then
var compassAngle = normalizeDegrees(compassDegrees);
The method you want is Math.Atan2. This takes two arguments - the y-value first, then the x-value - and it gives you an angle in radians.
Since you want an angle in degrees, you'll need to convert - the conversion factor is 180 / Math.PI. So you'll be using something like:
var radiansToDegrees = 180 / Math.PI;
progress.Value = Math.Atan2(y,x) * radiansToDegrees;
Depending exactly what combination of x and y needs to correspond to 0 you might need to add a number of degrees on afterwards. This as-is will give you 0 degrees for x = 1, y = 0, and 90 degrees for x = 0, y = 1, etc.

Calculating distance of cannon shot using utility tests in c# console application

I'm trying to calculate distance of cannon shot using velocity and angle. I'm testing results using utility tests. The formula for range should be someting like v^2 * sin2a aka velocity squared * sin2alpha . As far as i know, sin2a is supposed to be 2*sina*cosa, but i may be wrong.
Anyway, whatever i do, i get wrong results, because it doesn't seem to be calculating sin.
Here's the code
Cannon.cs
public int CalculateDistance(int angle, int velocity)
{
int distance = 0;
double radian_angle = (Math.PI / 180) * angle;
distance_of_shot = (Math.Pow(velocity, 2)) * (2 * Math.Sin(radian_angle) * Math.Cos(radian_angle));
distance = (int)distance_of_shot;
return distance;
}
CannonAttackTest.cs
[TestMethod]
public void Calculations()
{
Canon new_canon = new Canon();
var data = new_canon.CalculateDistance(45, 450);
Assert.AreEqual(20682, data);
}
The results is suppose to be 20682, but i get 202500, which is exactly a number of squared 450...whichs points to sin not being calculated.
Any help is appreciated!
Thank you!
Check your units, you need to divide by the value of "g" because velocity is m/s and your "distance of shot" is in m^2/s^2.
distance_of_shot = (Math.Pow(velocity, 2)) * (2 * Math.Sin(radian_angle) * Math.Cos(radian_angle))/9.81;
You have a mistake sin 0.70710678118654746 and cos 0.70710678118654757 but after
(2 * Math.Sin(radian_angle) * Math.Cos(radian_angle)) result coming 1

Kinect Joint Angle Calculation

Sorry about this but I need some conformation about this function and calculation
I currently have these Vectors:
Vector3D ElbowLeft = new Vector3D(body.Joints[JointType.ElbowLeft].Position.X, body.Joints[JointType.ElbowLeft].Position.Y, body.Joints[JointType.ElbowLeft].Position.Z);
Vector3D WristLeft = new Vector3D(body.Joints[JointType.WristLeft].Position.X, body.Joints[JointType.WristLeft].Position.Y, body.Joints[JointType.WristLeft].Position.Z);
Vector3D ShoulderLeft = new Vector3D(body.Joints[JointType.ShoulderLeft].Position.X, body.Joints[JointType.ShoulderLeft].Position.Y, body.Joints[JointType.ShoulderLeft].Position.Z);
Vector3D Head = new Vector3D(body.Joints[JointType.Head].Position.X, body.Joints[JointType.Head].Position.Y, body.Joints[JointType.Head].Position.Z);
Vector3D Neck = new Vector3D(body.Joints[JointType.Neck].Position.X, body.Joints[JointType.Neck].Position.Y, body.Joints[JointType.Neck].Position.Z);
Vector3D SpineShoulder = new Vector3D(body.Joints[JointType.SpineShoulder].Position.X, body.Joints[JointType.SpineShoulder].Position.Y, body.Joints[JointType.SpineShoulder].Position.Z);
I am calculating the angle between the two vectors using this function
public double AngleBetweenTwoVectors(Vector3D vectorA, Vector3D vectorB)
{
double dotProduct = 0.0;
vectorA.Normalize();
vectorB.Normalize();
dotProduct = Vector3D.DotProduct(vectorA, vectorB);
return (double)Math.Acos(dotProduct) / Math.PI * 180;
}
And I am calling it like this:
double LeftElbowAngle = AngleBetweenTwoVectors(ElbowLeft - ShoulderLeft, ElbowLeft - WristLeft);
double NeckAngle = AngleBetweenTwoVectors(Neck - Head, Neck - SpineBase);
Is this correct? Im just doubting myself because When i put my arm straight or stand up straight it detects an angle of about 170 - 175 rather than 180. on both my neck and my elbow joint
I have confirmed that the above Algorithim is correct mathematically, however the accuracy of the device may be a bit off due to the hardware, and individual human bones may prevent from perfect joint extension which is 180.
correct me If I'm wrong but I think instead of this
return (double)Math.Acos(dotProduct) / Math.PI * 180
it should be
return (double)Math.Acos(dotProduct) * (180.0/Math.PI);
since angle returned by Math.Acos is in radian and to convert it into degrees you should be multiplying it to 180/pi

Trigonometric calculation not working

My calculations show 75 * Cos(90) as zero. However, I get -22.46325...
I can confirm that it is NOT in radians because the radians value is -33.6055...
Here is what I have:
private static double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
static void Main(string[] args)
{
Console.WriteLine((75 * Math.Cos(RadianToDegree(90))).ToString());
}
Why am I getting a value of -22.46325 instead of 0?
input is taken as radians so you need to convert degrees to radians
Math.Cos expects inputs in radians, not degrees:
public static double Cos(double d)
Parameters
d
An angle, measured in radians.
You said
My calculations show 75 * Cos(90) as zero
so presumably you are working in degrees.
You therefore need to use
private static double DegreeToRadian(double angle)
{
return angle / (180.0 / Math.PI);
}
instead of
private static double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
to convert the angle into radians as Math.Cos expects.
See this link to an ideone.com snippet to confirm it.
The result is 4.59227382683391E-15 but since you're dealing with floating point numbers, the result of Math.Cos(x) will never be zero (see, e.g. this StackOverflow question).
You're passing in an argument to Math.Cos that your code suggests should be in degrees, while Math.Cos takes Radians.
See: https://msdn.microsoft.com/en-us/library/system.math.cos%28v=vs.110%29.aspx
You've got the conversion backwards:
private static double DegreesToRadians(double angle)
{
return angle * (Math.PI / 180.0 );
}
static void Main(string[] args)
{
Console.WriteLine((75 * Math.Cos(DegreeToRadians(90))).ToString());
}
Your RadianToDegree method given the argument of 90 returns value of 5156.62015617741. Which is passed to Math.Cos. Math.Cos expects the angle in radians as an argument. That 5156.62015617741 radians in degrees would be:
5156.62015617741 / PI * 180 = 295452.571501057 = 252.571501057
cos of 252.571501057 degrees is -0.299515394, times 75 in your code gives -22.463654606 that you see (plus-minus floating point error).
As others already mentioned, you got your transformation backwards.

Calculating the angle of an orthogonal triangle using the Arcsin in C#

I have the following code:
double x = sw.bonePos[0, (int)Bones.HipCenter].x;
double z = sw.bonePos[0, (int)Bones.HipCenter].z;
double hypotenusePower2 = Math.Pow(x, 2) + Math.Pow(z, 2);
double hypotenuse = Math.Sqrt(hypotenusePower2);
double angle = Math.Asin(z / hypotenuse);
I know that x,z, hypotenuse are correct and z / hypotenuse is correct because its always between -1 and 1. So I want to find the angle using the ArcSin like this but when I am printing for example Math.Asin(1) the result is 1.5707...
Am I using the wrong function? Is there any function in C# that returns the angle?
Example of input/output:
x: -0.000844396417960525
z: 0.857428431510925
hypotenuse: 0.857428847292063
angle: 1.5698115260652
x: 0.0198930986225605
z: 0.849016189575195
hypotenus: 0.849249212854266
angle: 1.54736984845028
The result you get is correct - asin of 1 is half of π, or approximately 1.5707 radians.
Functions returning angles usually return the results in radians. If you need the result in degrees, you need to convert the result as follows:
double degrees = angle * ( 180 / Math.Pi );
That's the right answer. The resulting angle is measured in radians. Math.Asin(1) should therefore be equal to π/2 &approx; 1.5707 radians, which matches your result.
If you wanted the value in degrees, multiply by 180/π. In this case, π/2 * 180/π would give you 90 degrees:
double degrees = radians * (180 / Math.Pi);

Categories

Resources