This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to calculate the angle between two points relative to the horizontal axis?
I've been looking for this for ages and it's just really annoying me so I've decided to just ask...
Provided I have two points (namely x1, y1, and x2, y2), I would like to calculate the angle between these two points, presuming that when y1 == y2 and x1 > x2 the angle is 180 degrees...
I have the below code that I have been working with (using knowledge from high school) and I just can't seem to produce the desired result.
float xDiff = x1 - x2;
float yDiff = y1 - y2;
return (float)Math.Atan2(yDiff, xDiff) * (float)(180 / Math.PI);
Thanks in advance, I'm getting so frustrated...
From what I've gathered, you want the following to hold:
Horizontal line: P1 -------- P2 => 0°
Horizontal line: P2 -------- P1 => 180°
Rotating the horizontal line clockwise
You said, you want the angle to increase in clockwise direction.
Rotating this line P1 -------- P2 such that P1 is above P2, the angle must thus be 90°.
If, however, we rotated in the opposite direction, P1 would be below P2 and the angle is -90° or 270°.
Working with atan2
Basis: Considering P1 to be the origin and measuring the angle of P2 relative to the origin, then P1 -------- P2 will correctly yield 0.
float xDiff = x2 - x1;
float yDiff = y2 - y1;
return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
However, atan2 let's the angle increase in CCW direction.
Rotating in CCW direction around the origin, y goes through the following values:
y = 0
y > 0
y = 0
y < 0
y = 0
This means, that we can simply invert the sign of y to flip the direction. But because C#'s coordinates increase from top to bottom, the sign is already reversed when computing yDiff.
Related
public double GetPitchToFace(double Z2, double Z1, double X2, double X1)
{
double Arc;
Arc = Math.Atan2(Z2 - Z1, X2 - X1);
Arc = (Arc >= 0) ? Arc+Math.PI : (2 * Math.PI + Arc);
return Arc;
}
I am attempting to calculate the correct pitch of a player in-game in order to face and travel to a waypoint.
It might be worth noting that the games coordinate system is Right-Handed.
I've confirmed that ATan2 is receiving the correct values yet the return value is incorrect.
It seems to be returning a downward pitch despite the waypoint being above the player. Yet other times it returns the seemingly correct pitch - I suspect this might have something to do when the point / player shift quadrants ?
(Minor side note - the reason I am 2 * Math.PI if Arc is >= 0 is simply the way the game stores and manages player pitch more info can be found here :
Pitch-Ingame
)
Here is an example of the above manually calculated :
Atan2(Z2 - Z1, X2 - X1)
Arc = Atan2(179.7 - 157.9, -3457.1-(-3432.1))
Arc = Atan2(21.7,-25.3)
Arc = 2.4 Radians
Arc = Arc + PI (without adding PI we return 137.51 degrees this is the opposite angle I need so I add PI to flip it to the correct side or add 180 degrees)
Arc = 5.5 Radians
Arc = 315,127 Degrees (this is a downwards trend from the point meaning we still miss the end point)
Here is the really bad plot of the above points
Please keep in mind that the points are plotted such as X,Z not X,Y
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.
We are using Unity C#. This image is a simplified 2D situation, in which we know the coordinates (x,y) of points p1 and p2.
We know the angle Theta, using this beauty
static float CalculateAngle(Vector3 p1, Vector3 p2)
{ return Quaternion.FromToRotation(Vector3.right, p1 - p2).eulerAngles.z; }
// The use of Vector3.right make zero degrees start at 3h00
// The values of z are irrelevant in this post, always zeroed.
Now a new point p3 shows up, imagine a screen touch, so we know it's coordinates (x,y). In essence, everything blue in the image, we know it's values.
The question is this: how to calculate a new p4 coordinates, in which
we know p3(x,y) coordinates
we don't know p4(x,y), except that:
p4.y has to be equal to p3.y
p4 is in line with p1 and p2
How to calculate the unknown p4.x, to have the full p4(x,y) coordinates, using Unity C#?
There may be easier solutions out there. The basic Math solution is as follows:
Calculate the linear function of p1 and p2 as mentioned here. An equation in the slope-intercept form is written as
y = mx + b
where m is the slope of the line and b is the y-intercept.
Insert P3's y into the form.
Solve x.
Example in C# for Unity:
Vector3 p1 = new Vector3(1f, 2f);
Vector3 p2 = new Vector3(2f, 3f);
Vector3 p3 = new Vector3(1000f, 5f);
Vector3 p4 = Vector3.zero;
float m = ((p2.y - p1.y) / (p2.x - p1.x));
float b = p1.y - (m * p1.x);
// x = ( y - b ) / m
p4.x = (p3.y - b) / m;
p4.y = p3.y;
print(p4); // (4.0, 5.0, 0.0) as expected
Linear functions are of the form y = mx + b, where m is the slope and b is the vertical shift. If P3 is a point with an xy values, then you can take the slope, the offset, and y and solve for x:
(y - b) / m = x
This is more of a general math question than a unity specific question; in the future, I'd suggest trying the stack exchange math site.
This will solve your problem, and it also works for p1,p2, and/or p3 with different depths:
Create a plane where Y=p3.y, and then raycast from p1->p2 to find where it intersects.
Plane plane = new Plane(Vector3.up, p3);
float enter;
Ray ray = new Ray(p1, p2-p1);
bool doesIntersect = plane.Raycast(ray, out enter);
if (doesIntersect) {
Vector3 p4 = ray.GetPoint(enter);
DoStuff(p4.x);
}
If you need to project along a non-horizontal direction, you'll need to use a different normal than Vector3.up.
i just get to the point and describe my problem .
Given a square not parallel to the axis !
i have (x1,y1) and (x2,y2) and the distance beetween them dx(width/height of the square)
i need to find the point (x,y) describe in the photo
(cant upload photo)
link to the image : the problem photo
first i tried the equation (x-x1)^2 + (y-y1)^2 = dx^2
(x-x2(^2 + (y-y2)^2 = 2 dx^2
but i cant manage to solve this equation when i try to code it ,
anyone have any idea's how to solve the problem in code or another equation or solution to find the point ?.
*i using c# 4,0
Very simple.
var dx = x2 - x1;
var dy = y2 - y1;
var rotatedDx = dy;
var rotatedDy = -dx;
x = x1 + rotatedDx;
y = y1 + rotatedDy;
Basically, you compute vector P1 -> P2 and rotate it by 90 degrees.
You can solve it using complex numbers by representing the points on an Argand diagram. (I think)
Since its a square, the sides are equal and 90degrees apart you can do this. (Refer to dropbox picture)
https://www.dropbox.com/s/ymimimgkuzhkcub/IMAG3818.jpg?dl=0
A is point (x1, y1) with value x1 + (y1)i
B is x2 + (y2)i
P and Q are the locations of the 2 possible places (x, y) can be and they are x + yi. Solve the 2 equation in the picture for values of x and y.
Herro
Its the First Time I'm posting Here
I'm New To C# But I'm Tying Something difficult
In the Illustration You Will Find
Coordinates Of a Arc
All Points Referenced From (0,0)
The X Axis is Horizontal
The Z Axis is Vertical
http://i.stack.imgur.com/ycmdi.png
Input Variables:
Xo,Zo =(529.819,343.509)
Xn,Zn =(529.26,343.678)
R(Radius) =(9.2)
I Need The Coordinates of I,K(Centrer Point,Referenced to 0,0)
The Answer to I,K is (I532.2,K352.396)
But I want to know how to calculate this
This Is Going to Be uses in G code Conversion
Eg:
N8(3)X529.819Z343.509$
N9(4)X529.26Z343.678R9.2C0$
To
N8(3)X529.819Z343.509$
N9(4)X529.26Z343.678I532.2K352.396$
(C0 & C1 is CW & CCW)
A copy/paste of some VB6 code I wrote ages ago, it runs on a lot of machines every day. It works by rotating the coordinate system by the angle between the two points, thus greatly simplifying the math. Tangent() returns the angle, Rotate() rotates a point, Sqr() is Math.Sqrt() in C#:
'--- Compute arc center from radius
Dim tang#, w#
tang = co1.Tangent(co2)
co2.Rotate co1, -tang
center.X = (co1.X + co2.X) / 2
center.Y = 0
w = center.X - co1.X
If Abs(mModal.RWord) < w Then
'--- R-word too small
If mModal.ThrowErr And w - Abs(mModal.RWord) > 0.00
Err.Raise 911, , "R-word too small"
End If
Else
center.Y = -Sqr(mModal.RWord * mModal.RWord - w * w
End If
'--- Choose out of the 4 possible arcs
If Not cw Then center.Y = -center.Y
If mModal.RWord < 0 Then center.Y = -center.Y
center.Y = center.Y + co1.Y
center.Rotate co1, tang
co2.Rotate co1, tang
GetArcCenter = center