Normalize the rectangles

This commit is contained in:
Antoine Vandecreme 2015-12-05 17:51:21 -05:00
parent fc919ff56d
commit 5e362554e2
2 changed files with 105 additions and 24 deletions

View File

@ -43,6 +43,8 @@
* y increases when going to the bottom * y increases when going to the bottom
* degrees increases clockwise with 0 being the horizontal * degrees increases clockwise with 0 being the horizontal
* *
* The constructor normalizes the rectangle to always have 0 <= degrees < 90
*
* @memberof OpenSeadragon * @memberof OpenSeadragon
* @param {Number} [x=0] The vector component 'x'. * @param {Number} [x=0] The vector component 'x'.
* @param {Number} [y=0] The vector component 'y'. * @param {Number} [y=0] The vector component 'y'.
@ -77,6 +79,35 @@ $.Rect = function(x, y, width, height, degrees) {
this.height = typeof(height) === "number" ? height : 0; this.height = typeof(height) === "number" ? height : 0;
this.degrees = typeof(degrees) === "number" ? degrees : 0; this.degrees = typeof(degrees) === "number" ? degrees : 0;
// Normalizes the rectangle.
this.degrees = this.degrees % 360;
if (this.degrees < 0) {
this.degrees += 360;
}
var newTopLeft, newWidth;
if (this.degrees >= 270) {
newTopLeft = this.getTopRight();
this.x = newTopLeft.x;
this.y = newTopLeft.y;
newWidth = this.height;
this.height = this.width;
this.width = newWidth;
this.degrees -= 270;
} else if (this.degrees >= 180) {
newTopLeft = this.getBottomRight();
this.x = newTopLeft.x;
this.y = newTopLeft.y;
this.degrees -= 180;
} else if (this.degrees >= 90) {
newTopLeft = this.getBottomLeft();
this.x = newTopLeft.x;
this.y = newTopLeft.y;
newWidth = this.height;
this.height = this.width;
this.width = newWidth;
this.degrees -= 90;
}
}; };
$.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
@ -257,10 +288,13 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
* @return {OpenSeadragon.Rect} * @return {OpenSeadragon.Rect}
*/ */
rotate: function(degrees, pivot) { rotate: function(degrees, pivot) {
degrees = (degrees + 360) % 360; degrees = degrees % 360;
if (degrees === 0) { if (degrees === 0) {
return this.clone(); return this.clone();
} }
if (degrees < 0) {
degrees += 360;
}
pivot = pivot || this.getCenter(); pivot = pivot || this.getCenter();
var newTopLeft = this.getTopLeft().rotate(degrees, pivot); var newTopLeft = this.getTopLeft().rotate(degrees, pivot);

View File

@ -36,6 +36,39 @@
strictEqual(rect.width, 0, 'rect.width should be 0'); strictEqual(rect.width, 0, 'rect.width should be 0');
strictEqual(rect.height, 0, 'rect.height should be 0'); strictEqual(rect.height, 0, 'rect.height should be 0');
strictEqual(rect.degrees, 0, 'rect.degrees should be 0'); strictEqual(rect.degrees, 0, 'rect.degrees should be 0');
rect = new OpenSeadragon.Rect(0, 0, 1, 2, -405);
Util.assessNumericValue(Math.sqrt(2) / 2, rect.x, precision,
'rect.x should be sqrt(2)/2');
Util.assessNumericValue(-Math.sqrt(2) / 2, rect.y, precision,
'rect.y should be -sqrt(2)/2');
Util.assessNumericValue(2, rect.width, precision,
'rect.width should be 2');
Util.assessNumericValue(1, rect.height, precision,
'rect.height should be 1');
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
rect = new OpenSeadragon.Rect(0, 0, 1, 2, 135);
Util.assessNumericValue(-Math.sqrt(2), rect.x, precision,
'rect.x should be -sqrt(2)');
Util.assessNumericValue(-Math.sqrt(2), rect.y, precision,
'rect.y should be -sqrt(2)');
Util.assessNumericValue(2, rect.width, precision,
'rect.width should be 2');
Util.assessNumericValue(1, rect.height, precision,
'rect.height should be 1');
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
rect = new OpenSeadragon.Rect(0, 0, 1, 1, 585);
Util.assessNumericValue(0, rect.x, precision,
'rect.x should be 0');
Util.assessNumericValue(-Math.sqrt(2), rect.y, precision,
'rect.y should be -sqrt(2)');
Util.assessNumericValue(1, rect.width, precision,
'rect.width should be 1');
Util.assessNumericValue(1, rect.height, precision,
'rect.height should be 1');
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
}); });
test('getTopLeft', function() { test('getTopLeft', function() {
@ -108,6 +141,20 @@
"Incorrect bottom right point with 135 rotation."); "Incorrect bottom right point with 135 rotation.");
}); });
test('times', function() {
var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 45);
var expected = new OpenSeadragon.Rect(2, 4, 6, 8, 45);
var actual = rect.times(2);
assertRectangleEquals(expected, actual, "Incorrect x2 rectangles.");
});
test('translate', function() {
var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 45);
var expected = new OpenSeadragon.Rect(2, 4, 3, 4, 45);
var actual = rect.translate(new OpenSeadragon.Point(1, 2));
assertRectangleEquals(expected, actual, "Incorrect translation.");
});
test('union', function() { test('union', function() {
var rect1 = new OpenSeadragon.Rect(2, 2, 2, 3); var rect1 = new OpenSeadragon.Rect(2, 2, 2, 3);
var rect2 = new OpenSeadragon.Rect(0, 1, 1, 1); var rect2 = new OpenSeadragon.Rect(0, 1, 1, 1);
@ -137,9 +184,9 @@
2, 2,
1, 1,
45); 45);
var actual = rect.rotate(45); var actual = rect.rotate(-675);
assertRectangleEquals(expected, actual, assertRectangleEquals(expected, actual,
"Incorrect rectangle after rotation of 45deg around center."); "Incorrect rectangle after rotation of -675deg around center.");
expected = new OpenSeadragon.Rect(0, 0, 2, 1, 33); expected = new OpenSeadragon.Rect(0, 0, 2, 1, 33);
actual = rect.rotate(33, rect.getTopLeft()); actual = rect.rotate(33, rect.getTopLeft());