From a6c02adeb6938e97aa6c78c67c0738bd5fda6bdc Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Tue, 17 Apr 2018 18:23:35 -0400 Subject: [ios, macos] Add trigonometric support to NSExpression. (#11716) * [ios, macos] Add acos NSExpresssion operator. * [ios, macos] Add asin NSExpresssion operator. * [ios, macos] Add atan NSExpresssion operator. * [ios, macos] Add cosine NSExpresssion operator. * [ios, macos] Add sine NSExpresssion operator. * [ios, macos] Add tangent NSExpresssion operator. * [ios, macos] Add log2 NSExpresssion operator. * [ios, macos] Update style authors documentation. --- .../darwin/docs/guides/For Style Authors.md.ejs | 14 ++--- platform/darwin/src/NSExpression+MGLAdditions.mm | 70 ++++++++++++++++++++++ platform/darwin/test/MGLExpressionTests.mm | 50 ++++++++++++++++ platform/ios/docs/guides/For Style Authors.md | 14 ++--- platform/macos/docs/guides/For Style Authors.md | 14 ++--- 5 files changed, 141 insertions(+), 21 deletions(-) diff --git a/platform/darwin/docs/guides/For Style Authors.md.ejs b/platform/darwin/docs/guides/For Style Authors.md.ejs index a3083571cf..bca894c063 100644 --- a/platform/darwin/docs/guides/For Style Authors.md.ejs +++ b/platform/darwin/docs/guides/For Style Authors.md.ejs @@ -380,24 +380,24 @@ In style specification | Method, function, or predicate type | Format string syn `^` | `raise:toPower:` | `2 ** 2` `+` | `add:to:` | `1 + 2` `abs` | `abs:` | `abs(-1)` -`acos` | | -`asin` | | -`atan` | | +`acos` | `mgl_acos:` | `mgl_acos(1)` +`asin` | `mgl_asin:` | `mgl_asin(0)` +`atan` | `mgl_atan:` | `mgl_atan(20)` `ceil` | `ceiling:` | `ceiling(0.99999)` -`cos` | | +`cos` | `mgl_cos:` | `mgl_cos(0)` `e` | | `%@` representing `NSNumber` containing `M_E` `floor` | `floor:` | `floor(-0.99999)` `ln` | `ln:` | `ln(2)` `ln2` | | `%@` representing `NSNumber` containing `M_LN2` `log10` | `log:` | `log(1)` -`log2` | | +`log2` | `mgl_log2:` | `mgl_log2(1024)` `max` | `max:` | `max({1, 2, 2, 3, 4, 7, 9})` `min` | `min:` | `min({1, 2, 2, 3, 4, 7, 9})` `pi` | | `%@` representing `NSNumber` containing `M_PI` `round` | `mgl_round:` | `mgl_round(1.5)` -`sin` | | +`sin` | `mgl_sin:` | `mgl_sin(0)` `sqrt` | `sqrt:` | `sqrt(2)` -`tan` | | +`tan` | `mgl_tan:` | `mgl_tan(0)` `zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoom` `heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity` diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 54f98c6ab9..46a463430b 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -68,6 +68,13 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = INSTALL_METHOD(mgl_step:from:stops:); INSTALL_METHOD(mgl_coalesce:); INSTALL_METHOD(mgl_does:have:); + INSTALL_METHOD(mgl_acos:); + INSTALL_METHOD(mgl_cos:); + INSTALL_METHOD(mgl_asin:); + INSTALL_METHOD(mgl_sin:); + INSTALL_METHOD(mgl_atan:); + INSTALL_METHOD(mgl_tan:); + INSTALL_METHOD(mgl_log2:); // Install functions that resemble control structures, taking arbitrary // numbers of arguments. Vararg aftermarket functions need to be declared @@ -97,6 +104,55 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = return @(round(number.doubleValue)); } +/** + Computes the principal value of the inverse cosine. + */ +- (NSNumber *)mgl_acos:(NSNumber *)number { + return @(acos(number.doubleValue)); +} + +/** + Computes the principal value of the cosine. + */ +- (NSNumber *)mgl_cos:(NSNumber *)number { + return @(cos(number.doubleValue)); +} + +/** + Computes the principal value of the inverse sine. + */ +- (NSNumber *)mgl_asin:(NSNumber *)number { + return @(asin(number.doubleValue)); +} + +/** + Computes the principal value of the sine. + */ +- (NSNumber *)mgl_sin:(NSNumber *)number { + return @(sin(number.doubleValue)); +} + +/** + Computes the principal value of the inverse tangent. + */ +- (NSNumber *)mgl_atan:(NSNumber *)number { + return @(atan(number.doubleValue)); +} + +/** + Computes the principal value of the tangent. + */ +- (NSNumber *)mgl_tan:(NSNumber *)number { + return @(tan(number.doubleValue)); +} + +/** + Computes the logarithm base two of the value. + */ +- (NSNumber *)mgl_log2:(NSNumber *)number { + return @(log2(number.doubleValue)); +} + /** A placeholder for a method that evaluates an interpolation expression. */ @@ -675,6 +731,13 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { @"ln": @"ln:", @"abs": @"abs:", @"round": @"mgl_round:", + @"acos" : @"mgl_acos:", + @"cos" : @"mgl_cos:", + @"asin" : @"mgl_asin:", + @"sin" : @"mgl_sin:", + @"atan" : @"mgl_atan:", + @"tan" : @"mgl_tan:", + @"log2" : @"mgl_log2:", @"floor": @"floor:", @"ceil": @"ceiling:", @"^": @"raise:toPower:", @@ -917,6 +980,13 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { @"lowercase:": @"downcase", @"length:": @"length", @"mgl_round:": @"round", + @"mgl_acos:" : @"acos", + @"mgl_cos:" : @"cos", + @"mgl_asin:" : @"asin", + @"mgl_sin:" : @"sin", + @"mgl_atan:" : @"atan", + @"mgl_tan:" : @"tan", + @"mgl_log2:" : @"log2", // Vararg aftermarket expressions need to be declared with an explicit and implicit first argument. @"MGL_LET": @"let", @"MGL_LET:": @"let", diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index e078c4f4b6..d7c86ed07c 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -503,6 +503,13 @@ using namespace std::string_literals; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_log2:" arguments:@[MGLConstantExpression(@1024)]]; + NSArray *jsonExpression = @[@"log2", @1024]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @10); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } { NSExpression *expression = [NSExpression expressionForFunction:@"raise:toPower:" arguments:arguments]; NSArray *jsonExpression = @[@"^", @1, @1]; @@ -531,6 +538,49 @@ using namespace std::string_literals; XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @(M_PI)); XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_acos:" arguments:@[MGLConstantExpression(@1)]]; + NSArray *jsonExpression = @[@"acos", @1]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_cos:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"cos", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_asin:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"asin", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_sin:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"sin", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_atan:" arguments:@[MGLConstantExpression(@20)]]; + NSArray *jsonExpression = @[@"atan", @20]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + NSNumber *value = [expression expressionValueWithObject:nil context:nil]; + XCTAssertEqualWithAccuracy(value.doubleValue, 1.52, 0.001); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_tan:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"tan", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } } - (void)testStringFormattingExpressionObject { diff --git a/platform/ios/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md index 1ce0a4bf4f..fa65b3ccb9 100644 --- a/platform/ios/docs/guides/For Style Authors.md +++ b/platform/ios/docs/guides/For Style Authors.md @@ -365,24 +365,24 @@ In style specification | Method, function, or predicate type | Format string syn `^` | `raise:toPower:` | `2 ** 2` `+` | `add:to:` | `1 + 2` `abs` | `abs:` | `abs(-1)` -`acos` | | -`asin` | | -`atan` | | +`acos` | `mgl_acos:` | `mgl_acos(1)` +`asin` | `mgl_asin:` | `mgl_asin(0)` +`atan` | `mgl_atan:` | `mgl_atan(20)` `ceil` | `ceiling:` | `ceiling(0.99999)` -`cos` | | +`cos` | `mgl_cos:` | `mgl_cos(0)` `e` | | `%@` representing `NSNumber` containing `M_E` `floor` | `floor:` | `floor(-0.99999)` `ln` | `ln:` | `ln(2)` `ln2` | | `%@` representing `NSNumber` containing `M_LN2` `log10` | `log:` | `log(1)` -`log2` | | +`log2` | `mgl_log2:` | `mgl_log2(1024)` `max` | `max:` | `max({1, 2, 2, 3, 4, 7, 9})` `min` | `min:` | `min({1, 2, 2, 3, 4, 7, 9})` `pi` | | `%@` representing `NSNumber` containing `M_PI` `round` | `mgl_round:` | `mgl_round(1.5)` -`sin` | | +`sin` | `mgl_sin:` | `mgl_sin(0)` `sqrt` | `sqrt:` | `sqrt(2)` -`tan` | | +`tan` | `mgl_tan:` | `mgl_tan(0)` `zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoom` `heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity` diff --git a/platform/macos/docs/guides/For Style Authors.md b/platform/macos/docs/guides/For Style Authors.md index c8e517a5bd..fff70d0a90 100644 --- a/platform/macos/docs/guides/For Style Authors.md +++ b/platform/macos/docs/guides/For Style Authors.md @@ -358,24 +358,24 @@ In style specification | Method, function, or predicate type | Format string syn `^` | `raise:toPower:` | `2 ** 2` `+` | `add:to:` | `1 + 2` `abs` | `abs:` | `abs(-1)` -`acos` | | -`asin` | | -`atan` | | +`acos` | `mgl_acos:` | `mgl_acos(1)` +`asin` | `mgl_asin:` | `mgl_asin(0)` +`atan` | `mgl_atan:` | `mgl_atan(20)` `ceil` | `ceiling:` | `ceiling(0.99999)` -`cos` | | +`cos` | `mgl_cos:` | `mgl_cos(0)` `e` | | `%@` representing `NSNumber` containing `M_E` `floor` | `floor:` | `floor(-0.99999)` `ln` | `ln:` | `ln(2)` `ln2` | | `%@` representing `NSNumber` containing `M_LN2` `log10` | `log:` | `log(1)` -`log2` | | +`log2` | `mgl_log2:` | `mgl_log2(1024)` `max` | `max:` | `max({1, 2, 2, 3, 4, 7, 9})` `min` | `min:` | `min({1, 2, 2, 3, 4, 7, 9})` `pi` | | `%@` representing `NSNumber` containing `M_PI` `round` | `mgl_round:` | `mgl_round(1.5)` -`sin` | | +`sin` | `mgl_sin:` | `mgl_sin(0)` `sqrt` | `sqrt:` | `sqrt(2)` -`tan` | | +`tan` | `mgl_tan:` | `mgl_tan(0)` `zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoom` `heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity` -- cgit v1.2.1