VOX
VOX

Reputation: 2923

get angle of a line from horizon

I want to know how to get an angle of a line A-B from horizontal axis X. Other questions in SO do that only between two lines. I'm aware I can always draw second line A-C and calculate but I'm wondering if there's a faster method.

EDIT: I'm very sure I'm not doing a premature optimization.

Upvotes: 9

Views: 7632

Answers (6)

CtrlDot
CtrlDot

Reputation: 3122

If you need all four quadrants, Atan2 is more suitable than Atan.

public static int GetAngleBetweenPoints(PointF pt1, PointF pt2)
{
    float dx = pt2.X - pt1.X;
    float dy = pt2.Y - pt1.Y;

    int deg = Convert.ToInt32(Math.Atan2(dy, dx) * (180 / Math.PI));
    if (deg < 0) { deg += 360; }

    return deg;
}

Upvotes: 3

Fernando
Fernando

Reputation: 121

    private double Angulo(int x1, int y1, int x2, int y2)
    {
        double degrees;

        // Avoid divide by zero run values.
        if (x2 - x1 == 0)
        {
            if (y2 > y1)
                degrees = 90;
            else
                degrees = 270;
        }
        else
        {
            // Calculate angle from offset.
            double riseoverrun = (double)(y2 - y1) / (double)(x2 - x1);
            double radians = Math.Atan(riseoverrun);
            degrees = radians * ((double)180 / Math.PI);

            // Handle quadrant specific transformations.       
            if ((x2 - x1) < 0 || (y2 - y1) < 0)
                degrees += 180;
            if ((x2 - x1) > 0 && (y2 - y1) < 0)
                degrees -= 180;
            if (degrees < 0)
                degrees += 360;
        }
        return degrees;
    }

Upvotes: 12

Justin L.
Justin L.

Reputation: 13600

You could also use arccosine, if your line is in the form [r_x,r_y], where r_x is the change in x and r_y is the change in y.

angle = arccos( r_x/( r_x*r_x + r_y*r_y ) )

It's slightly more opaque, but it's basically the dot product law:

angle = arccos (r . v)

Where r and v are both unit vectors (vectors of length 1). In our case, v is the vector [1,0], and r is

[r_x,r_y] / (r_x^2+r_y^2)

in order to make it a unit vector.

Upvotes: 1

Frank
Frank

Reputation: 2648

If

  1. The angle is small,
  2. you can live with small inaccuracies, and
  3. You can use the angle in radians and not degrees,

then there is a fast solution: Under these conditions, you can assume that tan(a) = a = atan(a), and hence just omit the atan() call.

Upvotes: 1

Bart van Heukelom
Bart van Heukelom

Reputation: 44104

You can use atan for that.

angle = atan((By-Ay)/(Bx-Ax))

Upvotes: 12

Charlie Salts
Charlie Salts

Reputation: 13488

The x-axis is actually a line with equation

y = 0

so you could use the solution you have already.

Upvotes: 0

Related Questions