Created
July 18, 2012 10:11
-
-
Save davidaurelio/3135390 to your computer and use it in GitHub Desktop.
A Point class that supports addition and subtraction of instances. Precision is 16bit fixed point per coordinate.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
A point constructor that creates objects supporting addition and subtraction. | |
The "trick" is to use 32bit integers and stuff two fixed 16bit fixed point | |
numbers into them that represent the coordinates of the point. | |
This approach has problems with overflow. E.g. when adding two points (0, 2) | |
and (0, -2), the addition will cause the y values to overflow into the 17th | |
bit, which is part of the x-value. When subtracting two points, e.g. | |
(.00390625, 0) - (0, -128) | |
bits 17-32 will underflow into bit 16, the sign bit of the y value | |
See it as inspiration to use more bit shifting ;-) | |
*/ | |
var factor = 0x100; | |
function Point(x, y) { | |
if (arguments.length === 1) { | |
// take advantage of the >> operator which leaves the sign bit untouched | |
y = (x << 16 >> 16) / factor; | |
x = (x >> 16) / factor; | |
} | |
this.x = +x || 0; | |
this.y = +y || 0; | |
} | |
Point.prototype.valueOf = function() { | |
/* | |
The return alue will be a 32bit int, allowing for 16 bits of precision | |
for each coordinate. | |
One bit is used for the sign, 7 bits are used for the integral part, | |
8 bits are used for the fractional part (fixed point number). | |
*/ | |
// get sign bit and 15 value bits | |
var x = (this.x * factor) & 0x80007fff; | |
var y = (this.y * factor) & 0x80007fff; | |
// combine sign and value into 16 bits | |
x = (x >>> 16) | (x & 0x7fff); | |
y = (y >>> 16) | (y & 0x7fff); | |
return x << 16 | y; | |
} | |
Point.prototype.toString = function() { | |
return '{' + [this.x, this.y] + '}'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment