mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 02:39:28 +00:00
Add Math.atan2 to the inbuilt math function
Math.atan2(y, x) -> angle
This commit is contained in:
parent
4d585279b0
commit
482308f5da
10 changed files with 73 additions and 3 deletions
|
@ -16,6 +16,10 @@ All notable changes to this project are documented in this file.
|
|||
- Do not trigger `current-item-changed` on `StandardListView` if `current-item` is set on the same value.
|
||||
- Fixed `TimePickerPopup` does not open minute view by click on selected hour.
|
||||
|
||||
### Slint Language
|
||||
|
||||
- Added math function `atan2`.
|
||||
|
||||
## [1.7.2] - 2024-08-14
|
||||
|
||||
### General
|
||||
|
|
|
@ -94,7 +94,7 @@ These functions are available both in the global scope and in the `Math` namespa
|
|||
|
||||
Return the absolute value, where T is a numeric type.
|
||||
|
||||
### `acos(float) -> angle`, `asin(float) -> angle`, `atan(float) -> angle`, `cos(angle) -> float`, `sin(angle) -> float`, `tan(angle) -> float`
|
||||
### `acos(float) -> angle`, `asin(float) -> angle`, `atan(float) -> angle`, `atan2(float, float) -> angle`, `cos(angle) -> float`, `sin(angle) -> float`, `tan(angle) -> float`
|
||||
|
||||
The trigonometry function. Note that the should be typed with `deg` or `rad` unit
|
||||
(for example `cos(90deg)` or `sin(slider.value * 1deg)`).
|
||||
|
|
|
@ -35,6 +35,7 @@ pub enum BuiltinFunction {
|
|||
ACos,
|
||||
ASin,
|
||||
ATan,
|
||||
ATan2,
|
||||
Log,
|
||||
Pow,
|
||||
SetFocusItem,
|
||||
|
@ -136,6 +137,10 @@ impl BuiltinFunction {
|
|||
BuiltinFunction::ACos | BuiltinFunction::ASin | BuiltinFunction::ATan => {
|
||||
Type::Function { return_type: Box::new(Type::Angle), args: vec![Type::Float32] }
|
||||
}
|
||||
BuiltinFunction::ATan2 => Type::Function {
|
||||
return_type: Box::new(Type::Angle),
|
||||
args: vec![Type::Float32, Type::Float32],
|
||||
},
|
||||
BuiltinFunction::Log | BuiltinFunction::Pow => Type::Function {
|
||||
return_type: Box::new(Type::Float32),
|
||||
args: vec![Type::Float32, Type::Float32],
|
||||
|
@ -342,7 +347,8 @@ impl BuiltinFunction {
|
|||
| BuiltinFunction::ASin
|
||||
| BuiltinFunction::Log
|
||||
| BuiltinFunction::Pow
|
||||
| BuiltinFunction::ATan => true,
|
||||
| BuiltinFunction::ATan
|
||||
| BuiltinFunction::ATan2 => true,
|
||||
BuiltinFunction::SetFocusItem | BuiltinFunction::ClearFocusItem => false,
|
||||
BuiltinFunction::ShowPopupWindow | BuiltinFunction::ClosePopupWindow => false,
|
||||
BuiltinFunction::SetSelectionOffsets => false,
|
||||
|
@ -407,7 +413,8 @@ impl BuiltinFunction {
|
|||
| BuiltinFunction::ASin
|
||||
| BuiltinFunction::Log
|
||||
| BuiltinFunction::Pow
|
||||
| BuiltinFunction::ATan => true,
|
||||
| BuiltinFunction::ATan
|
||||
| BuiltinFunction::ATan2 => true,
|
||||
BuiltinFunction::SetFocusItem | BuiltinFunction::ClearFocusItem => false,
|
||||
BuiltinFunction::ShowPopupWindow | BuiltinFunction::ClosePopupWindow => false,
|
||||
BuiltinFunction::SetSelectionOffsets => false,
|
||||
|
|
|
@ -3351,6 +3351,10 @@ fn compile_builtin_function_call(
|
|||
ctx.generator_state.conditional_includes.cmath.set(true);
|
||||
format!("std::atan({}) / {}", a.next().unwrap(), pi_180)
|
||||
}
|
||||
BuiltinFunction::ATan2 => {
|
||||
ctx.generator_state.conditional_includes.cmath.set(true);
|
||||
format!("std::atan2({}, {}) / {}", a.next().unwrap(), a.next().unwrap(), pi_180)
|
||||
}
|
||||
BuiltinFunction::SetFocusItem => {
|
||||
if let [llr::Expression::PropertyReference(pr)] = arguments {
|
||||
let window = access_window_field(ctx);
|
||||
|
|
|
@ -2725,6 +2725,10 @@ fn compile_builtin_function_call(
|
|||
BuiltinFunction::ASin => quote!((#(#a)* as f64).asin().to_degrees()),
|
||||
BuiltinFunction::ACos => quote!((#(#a)* as f64).acos().to_degrees()),
|
||||
BuiltinFunction::ATan => quote!((#(#a)* as f64).atan().to_degrees()),
|
||||
BuiltinFunction::ATan2 => {
|
||||
let (a1, a2) = (a.next().unwrap(), a.next().unwrap());
|
||||
quote!((#a1 as f64).atan2(#a2 as f64).to_degrees())
|
||||
}
|
||||
BuiltinFunction::Log => {
|
||||
let (a1, a2) = (a.next().unwrap(), a.next().unwrap());
|
||||
quote!((#a1 as f64).log(#a2 as f64))
|
||||
|
|
|
@ -92,6 +92,7 @@ fn builtin_function_cost(function: &BuiltinFunction) -> isize {
|
|||
BuiltinFunction::ACos => 10,
|
||||
BuiltinFunction::ASin => 10,
|
||||
BuiltinFunction::ATan => 10,
|
||||
BuiltinFunction::ATan2 => 10,
|
||||
BuiltinFunction::Log => 10,
|
||||
BuiltinFunction::Pow => 10,
|
||||
BuiltinFunction::SetFocusItem | BuiltinFunction::ClearFocusItem => isize::MAX,
|
||||
|
|
|
@ -802,6 +802,7 @@ impl LookupObject for MathFunctions {
|
|||
.or_else(|| f("asin", BuiltinFunctionReference(BuiltinFunction::ASin, sl())))
|
||||
.or_else(|| f("acos", BuiltinFunctionReference(BuiltinFunction::ACos, sl())))
|
||||
.or_else(|| f("atan", BuiltinFunctionReference(BuiltinFunction::ATan, sl())))
|
||||
.or_else(|| f("atan2", BuiltinFunctionReference(BuiltinFunction::ATan2, sl())))
|
||||
.or_else(|| f("log", BuiltinFunctionReference(BuiltinFunction::Log, sl())))
|
||||
.or_else(|| f("pow", BuiltinFunctionReference(BuiltinFunction::Pow, sl())))
|
||||
}
|
||||
|
|
|
@ -479,6 +479,11 @@ fn call_builtin_function(
|
|||
let x: f64 = eval_expression(&arguments[0], local_context).try_into().unwrap();
|
||||
Value::Number(x.atan().to_degrees())
|
||||
}
|
||||
BuiltinFunction::ATan2 => {
|
||||
let x: f64 = eval_expression(&arguments[0], local_context).try_into().unwrap();
|
||||
let y: f64 = eval_expression(&arguments[1], local_context).try_into().unwrap();
|
||||
Value::Number(x.atan2(y).to_degrees())
|
||||
}
|
||||
BuiltinFunction::Log => {
|
||||
let x: f64 = eval_expression(&arguments[0], local_context).try_into().unwrap();
|
||||
let y: f64 = eval_expression(&arguments[1], local_context).try_into().unwrap();
|
||||
|
|
35
tests/cases/expr/atan2.slint
Normal file
35
tests/cases/expr/atan2.slint
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
TestCase := Rectangle {
|
||||
property<angle> t1: atan2(0, 0);
|
||||
property<angle> t2: atan2(10, 10);
|
||||
property<angle> t3: atan2(10, -10);
|
||||
property<angle> t4: atan2(-10, 10);
|
||||
}
|
||||
/*
|
||||
```cpp
|
||||
auto handle = TestCase::create();
|
||||
const TestCase &instance = *handle;
|
||||
assert(std::abs(instance.get_t1()) < 0.0001);
|
||||
assert(std::abs(instance.get_t2() - 45.0) < 0.0001);
|
||||
assert(std::abs(instance.get_t3() - 135.0) < 0.0001);
|
||||
assert(std::abs(instance.get_t4() - -45.0) < 0.0001);
|
||||
```
|
||||
|
||||
```rust
|
||||
let instance = TestCase::new().unwrap();
|
||||
assert!(instance.get_t1().abs() < 0.0001);
|
||||
assert!((instance.get_t2() - 45.0).abs() < 0.0001);
|
||||
assert!((instance.get_t3() - 135.0).abs() < 0.0001);
|
||||
assert!((instance.get_t4() - -45.0).abs() < 0.0001);
|
||||
```
|
||||
|
||||
```js
|
||||
var instance = new slint.TestCase({});
|
||||
assert.equal(instance.t1, 0);
|
||||
assert.equal(instance.t2, 45);
|
||||
assert.equal(instance.t3, 135);
|
||||
assert.equal(instance.t4, -45);
|
||||
```
|
||||
*/
|
|
@ -11,6 +11,15 @@
|
|||
round(atan(tan(45deg))/0.1deg) == 450 &&
|
||||
round(asin(sin(45deg))/0.1deg) == 450 &&
|
||||
round(acos(cos(45deg))/0.1deg) == 450 &&
|
||||
atan2(0, 0) == 0 &&
|
||||
atan2(0, 10) == 0deg &&
|
||||
atan2(10, 10) == 45deg &&
|
||||
atan2(10, 0) == 90deg &&
|
||||
atan2(10, -10) == 135deg &&
|
||||
atan2(0, -10) == 180deg &&
|
||||
atan2(-10, -10) == -135deg &&
|
||||
atan2(-10, 0) == -90deg &&
|
||||
atan2(-10, 10) == -45deg &&
|
||||
true;
|
||||
property <bool> test: verify;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue