Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate a vector from the center of a square to edge based on radius

Tags:

math

vector

2d

Given a square (described by x, y, width, height) and an angle (in radians) I need to calculate a vector that originates at the squares centre and terminates at the point that collides with the edge of the square at the given angle.

I'm really most interested in the point it collides at so if that would make calculation more efficient let me know.

Can this be generalized to Rectangles? How about polygons in general?

like image 381
James Fassett Avatar asked Sep 03 '25 16:09

James Fassett


1 Answers

The vector will be center + (cos(angle), sin(angle))*magnitude. Given that you want to intersect this with a square, you need to determine magnitude. You can get that with a square with:

float abs_cos_angle= fabs(cos(angle));
float abs_sin_angle= fabs(sin(angle));
if (width/2/abs_cos_angle <= height/2/abs_sin_angle)
{
    magnitude= fabs(width/2/abs_cos_angle);
}
else
{
    magnitude= height/2/abs_sin_angle;
}

However, cos(angle) or sin(angle) could be zero, so you should cross multiply that out to get:

float abs_cos_angle= fabs(cos(angle));
float abs_sin_angle= fabs(sin(angle));
if (width/2*abs_sin_angle <= height/2*abs_cos_angle)
{
    magnitude= width/2/abs_cos_angle;
}
else
{
    magnitude= height/2/abs_sin_angle;
}

And you can trivially get the end point from that.

EDIT: Here's a snippet you can drop in place to verify this works with the currently accepted answer:

    double magnitude;
    double abs_cos_angle= fabs(cos(angle));
    double abs_sin_angle= fabs(sin(angle));
    if (width/2*abs_sin_angle <= height/2*abs_cos_angle)
    {
        magnitude= width/2/abs_cos_angle;
    }
    else
    {
        magnitude= height/2/abs_sin_angle;
    }

    double check_x= x + cos(angle)*magnitude;
    double check_y= y + sin(angle)*magnitude;

    printf("  a = %d deg: x = %lf; y = %lf\n",(int)(angle/pi*180),check_x,check_y);

Clearly this is applies to an axis aligned rectangle. You can do something similar by finding the closest intersection between the testing vector and every edge in a polygon. (You can optimize that further, but that's left as an exercise to the reader.)

like image 190
MSN Avatar answered Sep 05 '25 16:09

MSN