Add a `wrapAngle` utility function.
This takes a value in radians and returns a wrapped value in the range
of [-PI, PI).
MODIFY
src/mapInteractor.js
src/mapInteractor.js
@@ -1156,10 +1156,8 @@ var mapInteractor = function (args) {
}
if (m_state.zoomrotateAllowRotation) {
var theta = m_state.initialRotation + deltaTheta;
- /* Compute the delta in the range of [-PI, PI). This is involed to work
- * around modulo returning a signed value. */
- deltaTheta = ((theta - m_this.map().rotation()) % (Math.PI * 2) +
- Math.PI * 3) % (Math.PI * 2) - Math.PI;
+ /* Compute the delta in the range of [-PI, PI). */
+ deltaTheta = util.wrapAngle(theta - m_this.map().rotation());
/* If we reverse direction, don't rotate until some threshold is
* exceeded. This helps prevent rotation bouncing while panning. */
if (deltaTheta && (deltaTheta * (m_state.lastRotationDelta || 0) >= 0 ||

MODIFY
src/util/index.js
src/util/index.js
@@ -1020,6 +1020,23 @@ var util = module.exports = {
return {min: min, max: max};
},
+ /**
+ * Given a value in radians, return a value wrapped to the range [-PI, PI).
+ *
+ * @param {number} value A value in radians.
+ * @returns {number} The wrapped value.
+ */
+ wrapAngle: function (value) {
+ /* Module will only ensure that this is between [-2 PI, 2 PI). */
+ value = value % (Math.PI * 2);
+ if (value < -Math.PI) {
+ value += Math.PI * 2;
+ } else if (value >= Math.PI) {
+ value -= Math.PI * 2;
+ }
+ return value;
+ },
+
/**
* Escape any character in a string that has a code point >= 127.
*

MODIFY
tests/cases/util.js
tests/cases/util.js
@@ -124,4 +124,16 @@ describe('geo.util', function () {
expect(util.getMinMaxValues(values, 200, 300, true)).toEqual({min: 200, max: 300});
expect(util.getMinMaxValues(values, 100, 400, true)).toEqual({min: 181, max: 303});
});
+
+ it('wrapAngle', function () {
+ expect(util.wrapAngle(0)).toBe(0);
+ expect(util.wrapAngle(2)).toBe(2);
+ expect(util.wrapAngle(4)).toBe(4 - Math.PI * 2);
+ expect(util.wrapAngle(7)).toBe(7 - Math.PI * 2);
+ expect(util.wrapAngle(17)).toBe(17 - Math.PI * 6);
+ expect(util.wrapAngle(-2)).toBe(-2);
+ expect(util.wrapAngle(-4)).toBe(-4 + Math.PI * 2);
+ expect(util.wrapAngle(-7)).toBe(-7 + Math.PI * 2);
+ expect(util.wrapAngle(-17)).toBe(-17 + Math.PI * 6);
+ });
});

Add a `wrapAngle` utility function.

This takes a value in radians and returns a wrapped value in the range
of [-PI, PI).