Kwargs: leg helpers (#6459)

legLen, legAngX, legAngY moved to keyword arguments
This commit is contained in:
Adam Chalmers
2025-04-24 09:53:19 -05:00
committed by GitHub
parent 668f6671a9
commit b02dbd4fe6
11 changed files with 95 additions and 65 deletions

View File

@ -24,8 +24,8 @@ legAngX(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legAngX(
### Examples ### Examples
```js ```js
legAngX(5, 3) legAngX(hypotenuse = 5, leg = 3)
``` ```

View File

@ -24,8 +24,8 @@ legAngY(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legAngY(
### Examples ### Examples
```js ```js
legAngY(5, 3) legAngY(hypotenuse = 5, leg = 3)
``` ```

View File

@ -24,8 +24,8 @@ legLen(
| Name | Type | Description | Required | | Name | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `hypotenuse` | [`number`](/docs/kcl/types/number) | | Yes | | `hypotenuse` | [`number`](/docs/kcl/types/number) | The length of the triangle's hypotenuse | Yes |
| `leg` | [`number`](/docs/kcl/types/number) | | Yes | | `leg` | [`number`](/docs/kcl/types/number) | The length of one of the triangle's legs (i.e. non-hypotenuse side) | Yes |
### Returns ### Returns
@ -35,7 +35,7 @@ legLen(
### Examples ### Examples
```js ```js
legLen(5, 3) legLen(hypotenuse = 5, leg = 3)
``` ```

View File

@ -133520,7 +133520,7 @@
"tags": [ "tags": [
"utilities" "utilities"
], ],
"keywordArguments": false, "keywordArguments": true,
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -133533,6 +133533,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of the triangle's hypotenuse",
"labelRequired": true "labelRequired": true
}, },
{ {
@ -133546,6 +133547,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of one of the triangle's legs (i.e. non-hypotenuse side)",
"labelRequired": true "labelRequired": true
} }
], ],
@ -133565,7 +133567,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"legAngX(5, 3)" "legAngX(hypotenuse = 5, leg = 3)"
] ]
}, },
{ {
@ -133575,7 +133577,7 @@
"tags": [ "tags": [
"utilities" "utilities"
], ],
"keywordArguments": false, "keywordArguments": true,
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -133588,6 +133590,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of the triangle's hypotenuse",
"labelRequired": true "labelRequired": true
}, },
{ {
@ -133601,6 +133604,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of one of the triangle's legs (i.e. non-hypotenuse side)",
"labelRequired": true "labelRequired": true
} }
], ],
@ -133620,7 +133624,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"legAngY(5, 3)" "legAngY(hypotenuse = 5, leg = 3)"
] ]
}, },
{ {
@ -133630,7 +133634,7 @@
"tags": [ "tags": [
"utilities" "utilities"
], ],
"keywordArguments": false, "keywordArguments": true,
"args": [ "args": [
{ {
"name": "hypotenuse", "name": "hypotenuse",
@ -133643,6 +133647,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of the triangle's hypotenuse",
"labelRequired": true "labelRequired": true
}, },
{ {
@ -133656,6 +133661,7 @@
}, },
"required": true, "required": true,
"includeInSnippet": true, "includeInSnippet": true,
"description": "The length of one of the triangle's legs (i.e. non-hypotenuse side)",
"labelRequired": true "labelRequired": true
} }
], ],
@ -133675,7 +133681,7 @@
"unpublished": false, "unpublished": false,
"deprecated": false, "deprecated": false,
"examples": [ "examples": [
"legLen(5, 3)" "legLen(hypotenuse = 5, leg = 3)"
] ]
}, },
{ {

View File

@ -1277,7 +1277,7 @@ const part001 = startSketchOn(XY)
|> line(end = [3, 4], tag = $seg01) |> line(end = [3, 4], tag = $seg01)
|> line(end = [ |> line(end = [
min(segLen(seg01), myVar), min(segLen(seg01), myVar),
-legLen(segLen(seg01), myVar) -legLen(hypotenuse = segLen(seg01), leg = myVar)
]) ])
"#; "#;
@ -1292,7 +1292,7 @@ const part001 = startSketchOn(XY)
|> line(end = [3, 4], tag = $seg01) |> line(end = [3, 4], tag = $seg01)
|> line(end = [ |> line(end = [
min(segLen(seg01), myVar), min(segLen(seg01), myVar),
legLen(segLen(seg01), myVar) legLen(hypotenuse = segLen(seg01), leg = myVar)
]) ])
"#; "#;
@ -1684,7 +1684,7 @@ let shape = layer() |> patternTransform(instances = 10, transform = transform)
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn test_math_execute_with_functions() { async fn test_math_execute_with_functions() {
let ast = r#"const myVar = 2 + min(100, -1 + legLen(5, 3))"#; let ast = r#"const myVar = 2 + min(100, -1 + legLen(hypotenuse = 5, leg = 3))"#;
let result = parse_execute(ast).await.unwrap(); let result = parse_execute(ast).await.unwrap();
assert_eq!( assert_eq!(
5.0, 5.0,

View File

@ -615,22 +615,6 @@ impl Args {
Ok(numbers) Ok(numbers)
} }
pub(crate) fn get_hypotenuse_leg(&self) -> Result<(f64, f64, NumericType), KclError> {
let numbers = self.get_number_array_with_types()?;
if numbers.len() != 2 {
return Err(KclError::Type(KclErrorDetails {
message: format!("Expected a number array of length 2, found `{:?}`", numbers),
source_ranges: vec![self.source_range],
}));
}
let mut numbers = numbers.into_iter();
let a = numbers.next().unwrap();
let b = numbers.next().unwrap();
Ok(NumericType::combine_eq_coerce(a, b))
}
pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> { pub(crate) fn get_sketches(&self, exec_state: &mut ExecState) -> Result<(Vec<Sketch>, Sketch), KclError> {
let Some(arg0) = self.args.first() else { let Some(arg0) = self.args.first() else {
return Err(KclError::Semantic(KclErrorDetails { return Err(KclError::Semantic(KclErrorDetails {

View File

@ -30,6 +30,7 @@ pub mod utils;
use anyhow::Result; use anyhow::Result;
pub use args::Args; pub use args::Args;
use args::TyF64;
use indexmap::IndexMap; use indexmap::IndexMap;
use kcl_derive_docs::stdlib; use kcl_derive_docs::stdlib;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -40,7 +41,10 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
docs::StdLibFn, docs::StdLibFn,
errors::KclError, errors::KclError,
execution::{types::PrimitiveType, ExecState, KclValue}, execution::{
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitType},
ExecState, KclValue,
},
parsing::ast::types::Name, parsing::ast::types::Name,
}; };
@ -287,8 +291,10 @@ pub enum FunctionKind {
const DEFAULT_TOLERANCE: f64 = 0.0000001; const DEFAULT_TOLERANCE: f64 = 0.0000001;
/// Compute the length of the given leg. /// Compute the length of the given leg.
pub async fn leg_length(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn leg_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?; let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = inner_leg_length(hypotenuse, leg); let result = inner_leg_length(hypotenuse, leg);
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()])) Ok(KclValue::from_number_with_type(result, ty, vec![args.into()]))
} }
@ -296,10 +302,16 @@ pub async fn leg_length(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// Compute the length of the given leg. /// Compute the length of the given leg.
/// ///
/// ```no_run /// ```no_run
/// legLen(5, 3) /// legLen(hypotenuse = 5, leg = 3)
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legLen", name = "legLen",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"], tags = ["utilities"],
}] }]
fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
@ -307,19 +319,31 @@ fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
} }
/// Compute the angle of the given leg for x. /// Compute the angle of the given leg for x.
pub async fn leg_angle_x(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn leg_angle_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?; let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = inner_leg_angle_x(hypotenuse, leg); let result = inner_leg_angle_x(hypotenuse, leg);
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()])) Ok(KclValue::from_number_with_type(
result,
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)),
vec![args.into()],
))
} }
/// Compute the angle of the given leg for x. /// Compute the angle of the given leg for x.
/// ///
/// ```no_run /// ```no_run
/// legAngX(5, 3) /// legAngX(hypotenuse = 5, leg = 3)
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legAngX", name = "legAngX",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"], tags = ["utilities"],
}] }]
fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
@ -327,19 +351,31 @@ fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
} }
/// Compute the angle of the given leg for y. /// Compute the angle of the given leg for y.
pub async fn leg_angle_y(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn leg_angle_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (hypotenuse, leg, ty) = args.get_hypotenuse_leg()?; let hypotenuse: TyF64 = args.get_kw_arg_typed("hypotenuse", &RuntimeType::length(), exec_state)?;
let leg: TyF64 = args.get_kw_arg_typed("leg", &RuntimeType::length(), exec_state)?;
let (hypotenuse, leg, _ty) = NumericType::combine_eq_coerce(hypotenuse, leg);
let result = inner_leg_angle_y(hypotenuse, leg); let result = inner_leg_angle_y(hypotenuse, leg);
Ok(KclValue::from_number_with_type(result, ty, vec![args.into()])) Ok(KclValue::from_number_with_type(
result,
NumericType::Known(UnitType::Angle(UnitAngle::Degrees)),
vec![args.into()],
))
} }
/// Compute the angle of the given leg for y. /// Compute the angle of the given leg for y.
/// ///
/// ```no_run /// ```no_run
/// legAngY(5, 3) /// legAngY(hypotenuse = 5, leg = 3)
/// ``` /// ```
#[stdlib { #[stdlib {
name = "legAngY", name = "legAngY",
keywords = true,
unlabeled_first = false,
args = {
hypotenuse = { docs = "The length of the triangle's hypotenuse" },
leg = { docs = "The length of one of the triangle's legs (i.e. non-hypotenuse side)" },
},
tags = ["utilities"], tags = ["utilities"],
}] }]
fn inner_leg_angle_y(hypotenuse: f64, leg: f64) -> f64 { fn inner_leg_angle_y(hypotenuse: f64, leg: f64) -> f64 {

View File

@ -362,7 +362,7 @@ describe('testing math operators', () => {
expect(mem['myVar']?.value).toBe(6) expect(mem['myVar']?.value).toBe(6)
}) })
it('with nested callExpression', async () => { it('with nested callExpression', async () => {
const code = 'const myVar = 2 + min(100, legLen(5, 3))' const code = 'myVar = 2 + min(100, legLen(hypotenuse = 5, leg = 3))'
const mem = await exe(code) const mem = await exe(code)
expect(mem['myVar']?.value).toBe(6) expect(mem['myVar']?.value).toBe(6)
}) })
@ -372,15 +372,15 @@ describe('testing math operators', () => {
expect(mem['myVar']?.value).toBe(-3) expect(mem['myVar']?.value).toBe(-3)
}) })
it('with unaryExpression in callExpression', async () => { it('with unaryExpression in callExpression', async () => {
const code = 'const myVar = min(-legLen(5, 4), 5)' const code = 'const myVar = min(-legLen(hypotenuse = 5, leg = 4), 5)'
const code2 = 'const myVar = min(5 , -legLen(5, 4))' const code2 = 'const myVar = min(5 , -legLen(hypotenuse = 5, leg = 4))'
const mem = await exe(code) const mem = await exe(code)
const mem2 = await exe(code2) const mem2 = await exe(code2)
expect(mem['myVar']?.value).toBe(-3) expect(mem['myVar']?.value).toBe(-3)
expect(mem['myVar']?.value).toBe(mem2['myVar']?.value) expect(mem['myVar']?.value).toBe(mem2['myVar']?.value)
}) })
it('with unaryExpression in ArrayExpression', async () => { it('with unaryExpression in ArrayExpression', async () => {
const code = 'const myVar = [1,-legLen(5, 4)]' const code = 'const myVar = [1,-legLen(hypotenuse = 5, leg = 4)]'
const mem = await exe(code) const mem = await exe(code)
expect(mem['myVar']?.value).toEqual([ expect(mem['myVar']?.value).toEqual([
{ {
@ -397,9 +397,9 @@ describe('testing math operators', () => {
}) })
it('with unaryExpression in ArrayExpression in CallExpression, checking nothing funny happens when used in a sketch', async () => { it('with unaryExpression in ArrayExpression in CallExpression, checking nothing funny happens when used in a sketch', async () => {
const code = [ const code = [
'const part001 = startSketchOn(XY)', 'part001 = startSketchOn(XY)',
' |> startProfileAt([0, 0], %)', ' |> startProfileAt([0, 0], %)',
'|> line(end = [-2.21, -legLen(5, min(3, 999))])', '|> line(end = [-2.21, -legLen(hypotenuse = 5, leg = min(3, 999))])',
].join('\n') ].join('\n')
const mem = await exe(code) const mem = await exe(code)
const sketch = sketchFromKclValue(mem['part001'], 'part001') const sketch = sketchFromKclValue(mem['part001'], 'part001')
@ -415,7 +415,7 @@ describe('testing math operators', () => {
` |> line(end = [3, 4], tag = $seg01)`, ` |> line(end = [3, 4], tag = $seg01)`,
` |> line(end = [`, ` |> line(end = [`,
` min(segLen(seg01), myVar),`, ` min(segLen(seg01), myVar),`,
` -legLen(segLen(seg01), myVar)`, ` -legLen(hypotenuse = segLen(seg01), leg = myVar)`,
`])`, `])`,
``, ``,
].join('\n') ].join('\n')
@ -425,8 +425,8 @@ describe('testing math operators', () => {
expect((sketch as Sketch).paths?.[1]?.from).toEqual([3, 4]) expect((sketch as Sketch).paths?.[1]?.from).toEqual([3, 4])
expect((sketch as Sketch).paths?.[1]?.to).toEqual([6, 0]) expect((sketch as Sketch).paths?.[1]?.to).toEqual([6, 0])
const removedUnaryExp = code.replace( const removedUnaryExp = code.replace(
`-legLen(segLen(seg01), myVar)`, `-legLen(hypotenuse = segLen(seg01), leg = myVar)`,
`legLen(segLen(seg01), myVar)` `legLen(hypotenuse = segLen(seg01), leg = myVar)`
) )
const removedUnaryExpMem = await exe(removedUnaryExp) const removedUnaryExpMem = await exe(removedUnaryExp)
const removedUnaryExpMemSketch = sketchFromKclValue( const removedUnaryExpMemSketch = sketchFromKclValue(
@ -438,7 +438,8 @@ describe('testing math operators', () => {
expect((removedUnaryExpMemSketch as Sketch).paths?.[1]?.to).toEqual([6, 8]) expect((removedUnaryExpMemSketch as Sketch).paths?.[1]?.to).toEqual([6, 8])
}) })
it('with nested callExpression and binaryExpression', async () => { it('with nested callExpression and binaryExpression', async () => {
const code = 'const myVar = 2 + min(100, -1 + legLen(5, 3))' const code =
'const myVar = 2 + min(100, -1 + legLen(hypotenuse = 5, leg = 3))'
const mem = await exe(code) const mem = await exe(code)
expect(mem['myVar']?.value).toBe(5) expect(mem['myVar']?.value).toBe(5)
}) })

View File

@ -298,21 +298,21 @@ mySk1 = startSketchOn(XY)
describe('testing call Expressions in BinaryExpressions and UnaryExpressions', () => { describe('testing call Expressions in BinaryExpressions and UnaryExpressions', () => {
it('nested callExpression in binaryExpression', () => { it('nested callExpression in binaryExpression', () => {
const code = 'myVar = 2 + min(100, legLen(5, 3))' const code = 'myVar = 2 + min(100, legLen(hypotenuse = 5, leg = 3))'
const { ast } = code2ast(code) const { ast } = code2ast(code)
const recasted = recast(ast) const recasted = recast(ast)
if (err(recasted)) throw recasted if (err(recasted)) throw recasted
expect(recasted.trim()).toBe(code) expect(recasted.trim()).toBe(code)
}) })
it('nested callExpression in unaryExpression', () => { it('nested callExpression in unaryExpression', () => {
const code = 'myVar = -min(100, legLen(5, 3))' const code = 'myVar = -min(100, legLen(hypotenuse = 5, leg = 3))'
const { ast } = code2ast(code) const { ast } = code2ast(code)
const recasted = recast(ast) const recasted = recast(ast)
if (err(recasted)) throw recasted if (err(recasted)) throw recasted
expect(recasted.trim()).toBe(code) expect(recasted.trim()).toBe(code)
}) })
it('with unaryExpression in callExpression', () => { it('with unaryExpression in callExpression', () => {
const code = 'myVar = min(5, -legLen(5, 4))' const code = 'myVar = min(5, -legLen(hypotenuse = 5, leg = 4))'
const { ast } = code2ast(code) const { ast } = code2ast(code)
const recasted = recast(ast) const recasted = recast(ast)
if (err(recasted)) throw recasted if (err(recasted)) throw recasted
@ -322,7 +322,7 @@ describe('testing call Expressions in BinaryExpressions and UnaryExpressions', (
const code = [ const code = [
'part001 = startSketchOn(XY)', 'part001 = startSketchOn(XY)',
' |> startProfileAt([0, 0])', ' |> startProfileAt([0, 0])',
' |> line(end = [-2.21, -legLen(5, min(3, 999))])', ' |> line(end = [\n -2.21,\n -legLen(hypotenuse = 5, leg = min(3, 999))\n ])',
].join('\n') ].join('\n')
const { ast } = code2ast(code) const { ast } = code2ast(code)
const recasted = recast(ast) const recasted = recast(ast)

View File

@ -308,11 +308,11 @@ part001 = startSketchOn(XY)
|> angledLine(angle = myAng2, length = segLen(seg01)) // ln-angledLineToY-angle should become angledLine |> angledLine(angle = myAng2, length = segLen(seg01)) // ln-angledLineToY-angle should become angledLine
|> line(end = [ |> line(end = [
min(segLen(seg01), myVar), min(segLen(seg01), myVar),
legLen(segLen(seg01), myVar) legLen(hypotenuse = segLen(seg01), leg = myVar)
]) // ln-should use legLen for y ]) // ln-should use legLen for y
|> line(end = [ |> line(end = [
min(segLen(seg01), myVar), min(segLen(seg01), myVar),
-legLen(segLen(seg01), myVar) -legLen(hypotenuse = segLen(seg01), leg = myVar)
]) // ln-legLen but negative ]) // ln-legLen but negative
|> angledLine(angle = -112, length = segLen(seg01)) // ln-should become angledLine |> angledLine(angle = -112, length = segLen(seg01)) // ln-should become angledLine
|> angledLine(angle = myVar, length = segLen(seg01)) // ln-use segLen for second arg |> angledLine(angle = myVar, length = segLen(seg01)) // ln-use segLen for second arg
@ -321,11 +321,11 @@ part001 = startSketchOn(XY)
|> angledLine(angle = legAngX(segLen(seg01), myVar), lengthX = min(segLen(seg01), myVar)) // ln-should use legAngX to calculate angle |> angledLine(angle = legAngX(segLen(seg01), myVar), lengthX = min(segLen(seg01), myVar)) // ln-should use legAngX to calculate angle
|> angledLine(angle = 180 + legAngX(segLen(seg01), myVar), lengthX = min(segLen(seg01), myVar)) // ln-same as above but should have + 180 to match original quadrant |> angledLine(angle = 180 + legAngX(segLen(seg01), myVar), lengthX = min(segLen(seg01), myVar)) // ln-same as above but should have + 180 to match original quadrant
|> line(end = [ |> line(end = [
legLen(segLen(seg01), myVar), legLen(hypotenuse = segLen(seg01), leg = myVar),
min(segLen(seg01), myVar) min(segLen(seg01), myVar)
]) // ln-legLen again but yRelative ]) // ln-legLen again but yRelative
|> line(end = [ |> line(end = [
-legLen(segLen(seg01), myVar), -legLen(hypotenuse = segLen(seg01), leg = myVar),
min(segLen(seg01), myVar) min(segLen(seg01), myVar)
]) // ln-negative legLen yRelative ]) // ln-negative legLen yRelative
|> angledLine(angle = 58, length = segLen(seg01)) // ln-angledLineOfYLength-free should become angledLine |> angledLine(angle = 58, length = segLen(seg01)) // ln-angledLineOfYLength-free should become angledLine

View File

@ -453,7 +453,10 @@ const getMinAndSegLenVals = (
const segLenVal = createSegLen(referenceSegName) const segLenVal = createSegLen(referenceSegName)
return [ return [
createCallExpression('min', [segLenVal, varVal]), createCallExpression('min', [segLenVal, varVal]),
createCallExpression('legLen', [segLenVal, varVal]), createCallExpressionStdLibKw('legLen', null, [
createLabeledArg('hypotenuse', segLenVal),
createLabeledArg('leg', varVal),
]),
] ]
} }