There is another post here about Atan but I dont see any relevant answers:
C# - Why Math.Atan(Math.Tan(x)) != x?
Isn't Math.Atan the same as tan-1? On my calculator I do:
tan-1(1) and i get 45.
tan(45) = 1
In C#:
Math.Atan(1) = 0.78539816339744828 //
nowhere near the 45.
Math.Tan(45) = 1.6197751905438615 //1
dp over the < Piover2.
Whats happening here?
C# is treating the angles as radians; your calculator is using degrees.
Atan(1) is equal to π/4. This is the correct value when working in radians. The same can be said of the other calculations in the library.
Feel free to convert the values:
double DegreeToRadian(double angle) { return Math.PI * angle / 180.0; }
double RadianToDegree(double angle) { return angle * (180.0 / Math.PI); }
This means that 45 radians is equal to about 2578.31008 degrees, so the tangent you are looking for should be better expressed as tan(π/4) or if you don't mind "cheating": Math.Tan(Math.Atan(1)); // ~= 1. I'm fairly confident that had you tried that yourself, you'd have realized something reasonable was happening, and might have stumbled upon how radians relate to degrees.
Your calculator is in Degrees, C# is doing these calculations in Radians.
To get the correct values:
int angle = 45; //in degrees
int result = Math.Tan(45 * Math.PI/180);
int aTanResult = Math.Atan(result) *180/Math.PI;
Math.Atan returns a value in radians. Your calculator is using degrees. 0.7853... (pi/4) radians is 45 degrees. (And conversely Math.Tan(45) is telling you the tan of 45 radians.)
Related
I want to make a bot that will walk along points from two coordinates (X and Y), I have the coordinates of the character, his rotation angle (1-180 / (- 1) - (-180)), and the required point where he is should get there. How do I know if the angle of rotation is necessary for the person to look directly at the point?
I have been sitting with this for a long time, and my head refuses to think at all, I tried to solve this by creating an angle between the radius vector, but nothing came of it.
public static double GetRotation(Point Destination)
{
double cos = Destination.Y / Math.Sqrt(Destination.X * Destination.X + Destination.Y * Destination.Y);
double angle = Math.Acos(cos);
return angle;
}
With regard to this problem, I would suggest generally using tan rather than cos due to the fact to get the angle between two point (X and y), the difference in the points provide the opposite and adjacent sides of the triangle for the calculation, rather than adjacent and hypotenuse.
If the player is at position X,Y, and the new position to walk to is X2,Y2, the equation to calculate the relative angle between them should be tan-1((Y2-Y)/(X2-X)) with regards to the X plane.
I think the below implementation should work for your example (though you may need to subtract the current player angle the player is facing to get the difference):
public static double GetRotation(Point source, Point Destination)
{
double tan = (Destination.Y - source.Y) / (Destination.X -source.X);
double angle = Math.Atan(tan) * (180/Math.PI) // Converts to degrees from radians
return angle;
}
Apologies for the formatting, am currently on mobile.
dx = Destination.X - Person.X;
dy = Destination.Y - Person.Y;
directionangle = Math.Atan2(dy, dx); // in radians!
degrees = directionangle * 180 / Math.PI;
double mypercentslope = 1
With a calculator if I wanted to convert that to a degree, I'd simply do: arctan(0.01);
I've tried Math.Atan(0.01) and it's reporting an incorrect value. I've read that c# uses radians but not sure, based on that, how to accomplish what i need. Thanks all!
Yes, Math.Atan does give it's result in radians (from here). You could use this to convert to degrees:
private double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
(the above code snippet is taken from here)
so full working code might look like:
double myPercentSlope = 100;
double rads = Math.Atan(myPercentSlope/100);
double degrees = rads * (180.0 / Math.PI);
I am working on a Windows Phone 8 app and I am doing a location based search. I am using this example to find my current location which is working fine. I also have a list of latitude and longitude co-ordinates. What I want to do is find out from this list of latitude and longitude co-ordinates, which is the closest to my current location. I may also possibly modify this to find out the nearest 5 or 10 or something like that.
It sounds like it should be simple to find out but I don't know how to do it.
How do I find out which co-ordinates are closest to another?
Any help would be appreciated.
Thanks!
The actual distance requires a geodesic function:
http://en.wikipedia.org/wiki/Great-circle_distance
It is quite costly, so you want to filter first with another function that helps you trimming down the candidates and ordering them later on in your code.
In this prior pass you can use the euclidean distance:
http://en.wikipedia.org/wiki/Euclidean_distance
This two-pass approach greatly reduces computation costs (by factors of 10,000 if need be) and is described in Programming Pearls (chapter 8):
http://www.cs.bell-labs.com/cm/cs/pearls/
Since your distances are probably very short (e.g., < 25km) you can use a distance approximation vs. the Haversine formula. I would suggest using Pythagoras Theorem on an Equirectangular projection, which will correct for the curvature along the longitude lines. Below is a C# implementation:
// Convert Degress to Radians
//
private static double Deg2Rad( double deg )
{
return deg * Math.PI / 180;
}
// Get Distance between two lat/lng points using the PythagorsTheorm (a*a = (b*b + c*c))
// on an equirectangular projection
//
private double PythagorasEquirectangular( Geoposition coord1, Geoposition coord2 )
{
double lat1 = Deg2Rad( coord1.Coordinate.Latitude );
double lat2 = Deg2Rad( coord2.Coordinate.Latitude );
double lon1 = Deg2Rad( coord1.Coordinate.Longitude );
double lon2 = Deg2Rad( coord2.Coordinate.Longitude );
double R = 6371; // km
double x = (lon2-lon1) * Math.Cos((lat1+lat2)/2);
double y = (lat2-lat1);
double d= Math.Sqrt(x*x + y*y) * R;
return d;
}
// Find the closest point to your position
//
private Geoposition NearestPoint( List<Geoposition> points, Geoposition position )
{
double min_dist = 999999;
Geoposition closest = null;
// Calculate distance of each point in the list from your position
foreach ( Geoposition point in points )
{
double dist = PythagorasEquirectangular( position, point );
// keep track of which point is the current closest.
if ( dist < min_dist )
{
min_dist = dist;
closest = point;
}
}
// return the closest point
return closest;
}
The radius of the earth at equator = 6,371 km. The equator is divided into 360 degrees of longitude, so each degree at the equator represents approximately 111.32 km. Moving away from the equator towards a pole this distance decreases to zero at the pole.To calculate the distance at different latitudes multiply it by the cosine of the latitude
3 decimal places,0.001 degrees aproximates to
111.32 meters at equator
96.41meters at 30 degrees N/S
78.71 meters at 45 degrees N/S
55.66 meters at 60 degrees N/S
28.82 meters at 75 degrees N/S
For for small distances (100 meters) Pythagoras’ theorem can be used on an equirectangular projection to calculate distance. This is less complicated than Haversine or Spherical Law of Cosines but still allows for the convergence towards poles.
var R = 6371; // km
lat/lng in radians
In pseudo code as I don't know C#
var x = (lng2-lng1) * cos((lat1+lat2)/2);
var y = (lat2-lat1);
var d = sqrt(x*x + y*y) * R;
I'm working on a simple game and I'm trying to simplify part of the 2D collision reaction in the game. When certain objects hit walls, I'm calculating a collision normal (collisionPoint - objectCenter) and reflecting based on that normal. I'm interested in rounding that normal vector to its nearest 15° but I'm not sure of a good way to go about that.
My current thought is doing something like this
float angle = atan2(normal.Y, normal.X) * Rad2Deg;
float newAngle = ((int)(angle + 7.5f) / 15) * 15.0f * Deg2Rad;
vector2 newNormal = vector2(cos(newAngle), sin(newAngle));
Is this a reasonable way to do it? Is there a better way?
Try this:
float roundAngle = 15 * Deg2Rad;
float angle = (float)Math.Atan2(normal.Y, normal.X);
Vector2 newNormal;
if (angle % roundAngle != 0)
{
float newAngle = (float)Math.Round(angle / roundAngle) * roundAngle;
newNormal = new Vector2((float)Math.Cos(newAngle), (float)Math.Sin(newAngle));
}
else
{
newNormal = Vector2.Normalize(normal);
}
You don't need to add 7.5, take this example:
// 4 degrees should round to 0
(4 + 7.5) / 15 == 11.5 / 15 == 0.77
// When this gets rounded up to 1 and multiplied by 15 again, it becomes 15 degrees.
// Don't add 7.5, and you get this:
4 / 15 == 0.27
// When rounded, it becomes 0 and, as such the correct answer
// Now how about a negative number; -12
-12 / 15 == -0.8
// Again, when rounded we get the correct number
actually this is more correct if you want the nearest 15 degree angle :
do this:
newangle% = INT(((angle%+7.5)/15)*15)
INT ALWAYS rounds DOWN by default this should properly give you the nearest angle in any case that is positive or negative have fun!!
and add the part where you use degree to rad and rad to degree if needed INSIDE the parens (like right next to angle% if that angle is not given in degrees then use some sort of rad2deg multiplier inside there
this is more like how you would do this in basic, with some modification It will work in c code or such, well good luck!!
I am developing in application in XNA which draws random paths. Unfortunately, I'm out of touch with graphing, so I'm a bit stuck. My application needs to do the following:
Pick a random angle from my origin (0,0), which is simple.
Draw a circle in relation to that origin, 16px away (or any distance I specify), at the angle found above.
(Excuse my horrible photoshoping)
alt text http://www.refuctored.com/coor.png
The second circle at (16,16) would represent a 45 degree angle 16 pixels away from my origin.
I would like to have a method in which I pass in my distance and angle that returns a point to graph at. i.e.
private Point GetCoordinate(float angle, int distance)
{
// Do something.
return new Point(x,y);
}
I know this is simple, but agian, I'm pretty out of touch with graphing. Any help?
Thanks,
George
If the angle is in degrees, first do:
angle *= Math.PI / 180;
Then:
return new Point(distance * Math.Cos(angle), distance * Math.Sin(angle));
By the way, the point at (16, 16) is not 16 pixels away from the origin, but sqrt(16^2 + 16^2) = sqrt(512) =~ 22.63 pixels.
private Point GetCoordinate(float angle, int distance)
{
float x = cos(angle) * distance;
float y = sin(angle) * distance;
return new Point(x, y);
}
Note that the trigonometric functions probably take radians. If your angle is in degrees, divide by 180/Pi.
in general:
x = d * cos(theta)
y = d * sin(theta)
Where d is the distance from the origin and theta is the angle.
Learn the Pythagorean Theorem. Then this thread should have more specific details for you.