From 1ac89f5aa4e10ae098f535830f865bf549fac8b1 Mon Sep 17 00:00:00 2001 From: SillyInventor Date: Tue, 31 Jan 2017 19:05:54 -0500 Subject: [PATCH] Added new util function that sends tan function infinities correctly Changed mathop to call new math util Changed sin & cos to round correctly (to get 0) Added testing for the new math util function Added testing for the new mathop functions --- src/blocks/scratch3_operators.js | 7 ++++--- src/util/math-util.js | 20 ++++++++++++++++++++ test/unit/blocks_operators.js | 10 +++++++--- test/unit/util_math.js | 8 ++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/blocks/scratch3_operators.js b/src/blocks/scratch3_operators.js index eb2a98135..d51e30894 100644 --- a/src/blocks/scratch3_operators.js +++ b/src/blocks/scratch3_operators.js @@ -1,4 +1,5 @@ var Cast = require('../util/cast.js'); +var MathUtil = require('../util/math-util.js'); var Scratch3OperatorsBlocks = function (runtime) { /** @@ -126,9 +127,9 @@ Scratch3OperatorsBlocks.prototype.mathop = function (args) { case 'floor': return Math.floor(n); case 'ceiling': return Math.ceil(n); case 'sqrt': return Math.sqrt(n); - case 'sin': return Math.sin((Math.PI * n) / 180); - case 'cos': return Math.cos((Math.PI * n) / 180); - case 'tan': return Math.tan((Math.PI * n) / 180); + case 'sin': return parseFloat(Math.sin((Math.PI * n) / 180).toFixed(10)); + case 'cos': return parseFloat(Math.cos((Math.PI * n) / 180).toFixed(10)); + case 'tan': return MathUtil.tan(n); case 'asin': return (Math.asin(n) * 180) / Math.PI; case 'acos': return (Math.acos(n) * 180) / Math.PI; case 'atan': return (Math.atan(n) * 180) / Math.PI; diff --git a/src/util/math-util.js b/src/util/math-util.js index c27e730bb..6191fdec5 100644 --- a/src/util/math-util.js +++ b/src/util/math-util.js @@ -45,4 +45,24 @@ MathUtil.wrapClamp = function (n, min, max) { return n - (Math.floor((n - min) / range) * range); }; + +/** + * Convert a value from tan function in degrees. + * @param {!number} angle in degrees + * @return {!number} Correct tan value + */ +MathUtil.tan = function (angle) { + angle = angle % 360; + switch (angle) { + case -270: + case 90: + return Infinity; + case -90: + case 270: + return -Infinity; + default: + return parseFloat(Math.tan((Math.PI * angle) / 180).toFixed(10)); + } +}; + module.exports = MathUtil; diff --git a/test/unit/blocks_operators.js b/test/unit/blocks_operators.js index b88ff0f77..dc4110d25 100644 --- a/test/unit/blocks_operators.js +++ b/test/unit/blocks_operators.js @@ -160,9 +160,13 @@ test('mathop', function (t) { t.strictEqual(blocks.mathop({OPERATOR: 'floor', NUM: 1.5}), 1); t.strictEqual(blocks.mathop({OPERATOR: 'ceiling', NUM: 0.1}), 1); t.strictEqual(blocks.mathop({OPERATOR: 'sqrt', NUM: 1}), 1); - t.strictEqual(blocks.mathop({OPERATOR: 'sin', NUM: 1}), 0.01745240643728351); - t.strictEqual(blocks.mathop({OPERATOR: 'cos', NUM: 1}), 0.9998476951563913); - t.strictEqual(blocks.mathop({OPERATOR: 'tan', NUM: 1}), 0.017455064928217585); + t.strictEqual(blocks.mathop({OPERATOR: 'sin', NUM: 1}), 0.0174524064); + t.strictEqual(blocks.mathop({OPERATOR: 'sin', NUM: 90}), 1); + t.strictEqual(blocks.mathop({OPERATOR: 'cos', NUM: 1}), 0.9998476952); + t.strictEqual(blocks.mathop({OPERATOR: 'cos', NUM: 180}), -1); + t.strictEqual(blocks.mathop({OPERATOR: 'tan', NUM: 1}), 0.0174550649); + t.strictEqual(blocks.mathop({OPERATOR: 'tan', NUM: 90}), Infinity); + t.strictEqual(blocks.mathop({OPERATOR: 'tan', NUM: 180}), 0); t.strictEqual(blocks.mathop({OPERATOR: 'asin', NUM: 1}), 90); t.strictEqual(blocks.mathop({OPERATOR: 'acos', NUM: 1}), 0); t.strictEqual(blocks.mathop({OPERATOR: 'atan', NUM: 1}), 45); diff --git a/test/unit/util_math.js b/test/unit/util_math.js index b198ef1d3..4c728dce1 100644 --- a/test/unit/util_math.js +++ b/test/unit/util_math.js @@ -34,3 +34,11 @@ test('wrapClamp', function (t) { t.strictEqual(math.wrapClamp(100, 0, 10), 1); t.end(); }); + +test('tan', function (t) { + t.strictEqual(math.tan(90), Infinity); + t.strictEqual(math.tan(180), 0); + t.strictEqual(math.tan(-90), -Infinity); + t.strictEqual(math.tan(33), 0.6494075932); + t.end(); +});