Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating the mid point of a rotated rectangle in javascript

I am attempting to find the mid point of a rotated rectangle.

I have made a javascript function to do this but its outputting incorrect answers. I dont understand where I am going wrong in my math or maybe I am not converting everything to radians?

Can you tell me how I can get my function to correctly calculate the mid point of a rotated rectangle?

This JSFiddle demonstrates how I am getting incorrect values for the mid point: http://jsfiddle.net/HyFrX/1/

function getMidPoint( /*int*/ x, /*int*/ y, /*int*/ width, /*int*/ height, /*int(in degrees)*/ angle )
{
   width         = width/2;
   height        = height/2   
   var dist      = Math.sqrt( (Math.pow(width,2)) + (Math.pow(height,2)) );
   var degtorad  = Math.PI/180;
   x            += Math.cos(degtorad * (45+angle)) * dist;
   y            += Math.sin(degtorad * (45+angle)) * dist;
   return {px: x, py: y};
}

var p  = getMidPoint(50,90,200,300,0);
var p2 = getMidPoint(10,500,600,100,0);
alert("p1: "+p.px+","+p.py);     // Should be 150,240 right?
alert("p2: "+p2.px+","+p2.py);   // Should be 310,550 right?
like image 642
sazr Avatar asked Dec 21 '22 23:12

sazr


2 Answers

If we start with a rectangle of a given width w and height h, then its vertices are at:

  • (0,0)
  • (0,h)
  • (w,0)
  • (w,h)

Thus the centre is at the average of all of these

c = (2w,2h)/4
  = (w/2,h/2)
  = (w', h') // rename for convenience

Rotate using the 'anti-clockwise about the origin' rotation matrix:

M = [ cos a, -sin a
      sin a,  cos a ]

Giving us

Mc = (w' cos a - h' sin a, w' sin a + h' cos a)
   = (w' c' - h' s',       w' s' + h' c') // rename for convenience

Translate to the original coordinate system (just add the x,y coord):

Mc + O = (x + w' c' - h' s', y + w' s' + h' c')

So, in code:

function getMidPoint(x, y, width, height, angle_degrees) {
    var angle_rad = angle_degrees * Math.PI / 180;
    var cosa = Math.cos(angle_rad);
    var sina = Math.sin(angle_rad);
    var wp = width/2;
    var hp = height/2;
    return { px: ( x + wp * cosa - hp * sina ),
             py: ( y + wp * sina + hp * cosa ) };
}

JS Fiddle

The centroid of a rectangle is the centre, and the centroid of 4 points at the vertices is also the centre. So in general we can just average the coordinates of the vertices. Since we have to calculate the vertices as well, that doesn't really speed things up here, but ideally you would have two functions, one to calculate the vertices, and one to calculate the centre.

like image 105
Phil H Avatar answered May 18 '23 19:05

Phil H


The angle in rectangles is not 45 degrees so you need to find the angle.

function getMidPoint( /*int*/ x, /*int*/ y, /*int*/ width, /*int*/ height, /*int(in degrees)*/ angle )
{
   width         = width/2;
   height        = height/2   
   var dist      = Math.sqrt( (Math.pow(width,2)) + (Math.pow(height,2)) );
   var ang       = Math.atan(width/height);
   var degtorad  = Math.PI/180;
   x            += Math.cos(degtorad *angle+ang) * dist;
   y            += Math.sin(degtorad *angle+ang) * dist;
   return {px: x, py: y};
}

var p  = getMidPoint(50,90,200,300,0);
var p2 = getMidPoint(10,500,600,100,0);
alert("p1: "+p.px+","+p.py);     // Should be 150,240 right?
alert("p2: "+p2.px+","+p2.py);   // Should be 310,550 right?
like image 39
qw3n Avatar answered May 18 '23 21:05

qw3n