user28277546
user28277546

Reputation:

How to calculate the angle between the x-axis and the line along which a generic polygon develops most?

I would like to calculate the angle between the x-axis of the reference system and the line along which a generic simple, convex or concave polygon develops most. By having the points of its vertices and the centroid.

In the image I have shown an example, where the blue line represents the line along which the polygon develops most.

The yellow circle (sorry if you can barely see it) represents the centroid, while the red circle represents the midpoint of the polygon.

Example of what I mean: example of what I mean

I tried to solve the problem by calculating, the eigenvectors associated with the largest eigenvalue of the covariance matrix.

I have done several tests and it seems to work, but when it tries to calculate the angle of this polygon it returns a value of about 80°, whereas what I expect is 0°.

Incorrect result: incorrect result

I'm not sure if I simply got the math wrong here, or if there's a flaw in my C# implementation (shown below):

// Returns the angle between the x-axis and the line along which the figure extends mainly.
public double GetOrientation()
{
    Point centroid = this.GetCentroid(); // Centroid of the polygon.
    int vertexesNumber = this.GetVertexesNumber(); // Number of vertexes of the polygon.
    double covXX = 0.0; // Variance of x, indicates how much x varies from the mean.
    double covYY = 0.0; // Variance of y, indicates how much y varies from the mean.
    double covXY = 0.0; // Covariance between x and y, indicates how much x and y vary together.

    // Calculates the covariance matrix, indicates how the vertexes are distributed with respect to the centroid.
    foreach (Point vertex in vertexes) // For each vertex of the polygon.
    {
        double x = vertex.X - centroid.X; // Calculates the difference of the vertex at x from the centroid at x.
        double y = vertex.Y - centroid.Y; // Calculates the difference of the vertex at y from the centroid at y.
        covXX += x * x; // Adds the square of the deviation from x to the centroid.
        covYY += y * y; // Adds the square of the deviation from y to the centroid.
        covXY += x * y; // Adds the product of deviations from x and y.
    }
    covXX /= vertexesNumber; // Calculates the mean of the variance along x.
    covYY /= vertexesNumber; // Calculates the mean of the variance along y.
    covXY /= vertexesNumber; // Calculates the mean of the covariance between x and y.

    double tr = covXX + covYY; // Calculates the trace of the matrix.
    double det = covXX * covYY - covXY * covXY; // Calculates the determinant of the matrix.

    double lambda = (tr + Math.Sqrt(tr * tr - 4 * det)) / 2; // Calculates the greatest eigenvalue of the matrix.
    double a1 = covXY; // Calculates the component along the x-axis of the eigenvector associated with the greatest eigenvalue.
    double a2 = lambda - covXX; // Calculates the component along the y-axis of the eigenvector associated with the greatest eigenvalue.

    double angle = Math.Atan2(a2, a1); // Calculates the angle between the x-axis and the line along which the polygon extends mainly, defined by the vector a1, a2.
    angle *= 180.0 / Math.PI; // Converts the angle from radians to degrees.

    return angle;
}

Upvotes: 1

Views: 85

Answers (0)

Related Questions