PowerToys Run Calculator: Add trigonometric angle unit conversion functions (#37475)

* Added trig unit conversion macros to PowerToys Run Calculator plugin.

* Added testing for unit conversions.

* Removed debug messages.
This commit is contained in:
Nathan Gill
2025-02-21 13:19:12 +00:00
committed by GitHub
parent 6515374ce9
commit 908a690316
3 changed files with 135 additions and 4 deletions

View File

@@ -59,8 +59,14 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
input = CalculateHelper.FixHumanMultiplicationExpressions(input);
// Get the user selected trigonometry unit
TrigMode trigMode = Main.GetTrigMode();
// Modify trig functions depending on angle unit setting
input = CalculateHelper.UpdateTrigFunctions(input, Main.GetTrigMode());
input = CalculateHelper.UpdateTrigFunctions(input, trigMode);
// Expand conversions between trig units
input = CalculateHelper.ExpandTrigConversions(input, trigMode);
var result = _magesEngine.Interpret(input);

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using static Microsoft.PowerToys.Run.Plugin.Calculator.CalculateEngine;
namespace Microsoft.PowerToys.Run.Plugin.Calculator
{
@@ -18,6 +19,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
@"factorial\s*\(|sign\s*\(|round\s*\(|rand\s*\(\)|randi\s*\([^\)]|" +
@"sin\s*\(|cos\s*\(|tan\s*\(|arcsin\s*\(|arccos\s*\(|arctan\s*\(|" +
@"sinh\s*\(|cosh\s*\(|tanh\s*\(|arsinh\s*\(|arcosh\s*\(|artanh\s*\(|" +
@"rad\s*\(|deg\s*\(|grad\s*\(|" + /* trigonometry unit conversion macros */
@"pi|" +
@"==|~=|&&|\|\||" +
@"((-?(\d+(\.\d*)?)|-?(\.\d+))[Ee](-?\d+))|" + /* expression from CheckScientificNotation between parenthesis */
@@ -26,7 +28,9 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
RegexOptions.Compiled);
private const string DegToRad = "(pi / 180) * ";
private const string DegToGrad = "(10 / 9) * ";
private const string GradToRad = "(pi / 200) * ";
private const string GradToDeg = "(9 / 10) * ";
private const string RadToDeg = "(180 / pi) * ";
private const string RadToGrad = "(200 / pi) * ";
@@ -266,10 +270,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
return input;
}
public static string UpdateTrigFunctions(string input, CalculateEngine.TrigMode mode)
public static string UpdateTrigFunctions(string input, TrigMode mode)
{
string modifiedInput = input;
if (mode == CalculateEngine.TrigMode.Degrees)
if (mode == TrigMode.Degrees)
{
modifiedInput = ModifyTrigFunction(modifiedInput, "sin", DegToRad);
modifiedInput = ModifyTrigFunction(modifiedInput, "cos", DegToRad);
@@ -278,7 +282,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
modifiedInput = ModifyTrigFunction(modifiedInput, "arccos", RadToDeg);
modifiedInput = ModifyTrigFunction(modifiedInput, "arctan", RadToDeg);
}
else if (mode == CalculateEngine.TrigMode.Gradians)
else if (mode == TrigMode.Gradians)
{
modifiedInput = ModifyTrigFunction(modifiedInput, "sin", GradToRad);
modifiedInput = ModifyTrigFunction(modifiedInput, "cos", GradToRad);
@@ -290,5 +294,39 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
return modifiedInput;
}
private static string ModifyMathFunction(string input, string function, string modification)
{
// Create the pattern to match the function, opening bracket, and any spaces in between
string pattern = $@"{function}\s*\(";
return Regex.Replace(input, pattern, modification + "(");
}
public static string ExpandTrigConversions(string input, TrigMode mode)
{
string modifiedInput = input;
// Expand "rad", "deg" and "grad" to their respective conversions for the current trig unit
if (mode == TrigMode.Radians)
{
modifiedInput = ModifyMathFunction(modifiedInput, "deg", DegToRad);
modifiedInput = ModifyMathFunction(modifiedInput, "grad", GradToRad);
modifiedInput = ModifyMathFunction(modifiedInput, "rad", string.Empty);
}
else if (mode == TrigMode.Degrees)
{
modifiedInput = ModifyMathFunction(modifiedInput, "deg", string.Empty);
modifiedInput = ModifyMathFunction(modifiedInput, "grad", GradToDeg);
modifiedInput = ModifyMathFunction(modifiedInput, "rad", RadToDeg);
}
else if (mode == TrigMode.Gradians)
{
modifiedInput = ModifyMathFunction(modifiedInput, "deg", DegToGrad);
modifiedInput = ModifyMathFunction(modifiedInput, "grad", string.Empty);
modifiedInput = ModifyMathFunction(modifiedInput, "rad", RadToGrad);
}
return modifiedInput;
}
}
}