diff --git a/docs/kcl-std/functions/std-sketch-ellipse.md b/docs/kcl-std/functions/std-sketch-ellipse.md index b7cac847cdb..cbe1144bf9b 100644 --- a/docs/kcl-std/functions/std-sketch-ellipse.md +++ b/docs/kcl-std/functions/std-sketch-ellipse.md @@ -13,8 +13,10 @@ Construct a 2-dimensional ellipse, of the specified major/minor radius, centered ellipse( @sketchOrSurface: Sketch | Plane | Face, center: Point2d, - minorRadius: number(Length), + minorRadius?: number(Length), + minorDiameter?: number(Length), majorRadius?: number(Length), + majorDiameter?: number(Length), majorAxis?: Point2d, tag?: tag, ): Sketch @@ -28,8 +30,10 @@ ellipse( |----------|------|-------------|----------| | `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes | | `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the ellipse. | Yes | -| `minorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor radius of the ellipse. | Yes | -| `majorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major radius of the ellipse. Equivalent to majorAxis = [majorRadius, 0]. | No | +| `minorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor radius of the ellipse. Incompatible with `minorDiameter`. | No | +| `minorDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor diameter of the ellipse. Incompatible with `minorRadius`. | No | +| `majorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major radius of the ellipse. Equivalent to majorAxis = [majorRadius, 0]. Incompatible with `majorDiameter`. | No | +| `majorDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major diameter of the ellipse. Equivalent to 2.0 * majorRadius. Incompatible with `majorRadius`. | No | | `majorAxis` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The major axis of the ellipse. | No | | `tag` | `tag` | Create a new tag which refers to this ellipse. | No | @@ -62,4 +66,26 @@ exampleSketch = startSketchOn(XY) > +```kcl +@settings(experimentalFeatures = allow) + +exampleSketch = startSketchOn(YZ) + |> ellipse(center = [10, 10], majorDiameter = 40, minorRadius = 10) + +``` + + + + + diff --git a/docs/kcl-std/functions/std-sketch-elliptic.md b/docs/kcl-std/functions/std-sketch-elliptic.md index 19f4a21bb32..4b4df643bd8 100644 --- a/docs/kcl-std/functions/std-sketch-elliptic.md +++ b/docs/kcl-std/functions/std-sketch-elliptic.md @@ -15,8 +15,10 @@ elliptic( center: Point2d, angleStart: number(Angle), angleEnd: number(Angle), - minorRadius: number(Length), + minorRadius?: number(Length), + minorDiameter?: number(Length), majorRadius?: number(Length), + majorDiameter?: number(Length), majorAxis?: Point2d, tag?: tag, ): Sketch @@ -32,8 +34,10 @@ elliptic( | `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the ellipse. | Yes | | `angleStart` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the ellptic should this segment start? | Yes | | `angleEnd` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the ellptic should this segment end? | Yes | -| `minorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor radius, b, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. | Yes | -| `majorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major radius, a, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Equivalent to majorAxis = [majorRadius, 0]. | No | +| `minorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor radius, b, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Incompatible with `minorDiameter`. | No | +| `minorDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The minor diameter of the elliptic equation. Incompatible with `minorRadius`. | No | +| `majorRadius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major radius, a, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Equivalent to majorAxis = [majorRadius, 0]. Incompatible with `majorDiameter`. | No | +| `majorDiameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The major diameter of the elliptic equation. Incompatible with `majorRadius`. | No | | `majorAxis` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The major axis of the elliptic. | No | | `tag` | `tag` | Create a new tag which refers to this arc. | No | diff --git a/docs/kcl-std/functions/std-sketch-ellipticPoint.md b/docs/kcl-std/functions/std-sketch-ellipticPoint.md index f4afc5442ea..9233519a00d 100644 --- a/docs/kcl-std/functions/std-sketch-ellipticPoint.md +++ b/docs/kcl-std/functions/std-sketch-ellipticPoint.md @@ -9,8 +9,10 @@ Calculate the point (x, y) on an ellipse given x or y and the center and major/m ```kcl ellipticPoint( - majorRadius: number, - minorRadius: number, + majorRadius?: number, + majorDiameter?: number, + minorRadius?: number, + minorDiameter?: number, x?: number(Length), y?: number(Length), ): Point2d @@ -22,8 +24,10 @@ ellipticPoint( | Name | Type | Description | Required | |----------|------|-------------|----------| -| `majorRadius` | [`number`](/docs/kcl-std/types/std-types-number) | The major radius, a, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. | Yes | -| `minorRadius` | [`number`](/docs/kcl-std/types/std-types-number) | The minor radius, b, of the hyperbolic equation x^2 / a ^ 2 + y^2 / b^2 = 1. | Yes | +| `majorRadius` | [`number`](/docs/kcl-std/types/std-types-number) | The major radius, a, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. Incompatible with `majorDiameter`. | No | +| `majorDiameter` | [`number`](/docs/kcl-std/types/std-types-number) | The major diameter of the elliptic equation. Incompatible with `majorRadius`. | No | +| `minorRadius` | [`number`](/docs/kcl-std/types/std-types-number) | The minor radius, b, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. Incompatible with `minorDiameter`. | No | +| `minorDiameter` | [`number`](/docs/kcl-std/types/std-types-number) | The minor diameter of the elliptic equation. Incompatible with `minorRadius`. | No | | `x` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The x value. Calculates y and returns (x, y). Incompatible with `y`. | No | | `y` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The y value. Calculates x and returns (x, y). Incompatible with `x`. | No | diff --git a/rust/kcl-derive-docs/src/example_tests.rs b/rust/kcl-derive-docs/src/example_tests.rs index 660897af889..a41c3bbf7ab 100644 --- a/rust/kcl-derive-docs/src/example_tests.rs +++ b/rust/kcl-derive-docs/src/example_tests.rs @@ -189,6 +189,7 @@ pub const TEST_NAMES: &[&str] = &[ "std-sketch-hyperbolic-0", "std-sketch-hyperbolicPoint-0", "std-sketch-ellipse-0", + "std-sketch-ellipse-1", "std-sketch-elliptic-0", "std-sketch-ellipticPoint-0", "std-sketch-tangentialArc-0", diff --git a/rust/kcl-lib/src/std/shapes.rs b/rust/kcl-lib/src/std/shapes.rs index 4382eebe73e..30d63c9ead8 100644 --- a/rust/kcl-lib/src/std/shapes.rs +++ b/rust/kcl-lib/src/std/shapes.rs @@ -528,10 +528,40 @@ pub async fn ellipse(exec_state: &mut ExecState, args: Args) -> Result = args.get_kw_arg_opt("majorDiameter", &RuntimeType::length(), exec_state)?; let major_axis = args.get_kw_arg_opt("majorAxis", &RuntimeType::point2d(), exec_state)?; - let minor_radius = args.get_kw_arg("minorRadius", &RuntimeType::length(), exec_state)?; + let minor_radius = args.get_kw_arg_opt("minorRadius", &RuntimeType::length(), exec_state)?; + let minor_diameter: Option = args.get_kw_arg_opt("minorDiameter", &RuntimeType::length(), exec_state)?; let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?; + let major_radius = match (major_radius, major_diameter) { + (Some(_), Some(_)) | (None, None) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `majorDiameter` or `majorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (Some(major_radius), _) => Some(major_radius), + (_, Some(major_diameter)) => Some(TyF64 { + n: 0.5 * major_diameter.n, + ty: major_diameter.ty, + }), + }; + + let minor_radius = match (minor_radius, minor_diameter) { + (Some(_), Some(_)) | (None, None) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `minorDiameter` or `minorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (Some(minor_radius), _) => minor_radius, + (_, Some(minor_diameter)) => TyF64 { + n: 0.5 * minor_diameter.n, + ty: minor_diameter.ty, + }, + }; + let sketch = inner_ellipse( sketch_or_surface, center, diff --git a/rust/kcl-lib/src/std/sketch.rs b/rust/kcl-lib/src/std/sketch.rs index 226a854217c..650410ca0fe 100644 --- a/rust/kcl-lib/src/std/sketch.rs +++ b/rust/kcl-lib/src/std/sketch.rs @@ -1920,9 +1920,38 @@ async fn inner_subtract_2d( pub async fn elliptic_point(exec_state: &mut ExecState, args: Args) -> Result { let x = args.get_kw_arg_opt("x", &RuntimeType::length(), exec_state)?; let y = args.get_kw_arg_opt("y", &RuntimeType::length(), exec_state)?; - let major_radius = args.get_kw_arg("majorRadius", &RuntimeType::num_any(), exec_state)?; - let minor_radius = args.get_kw_arg("minorRadius", &RuntimeType::num_any(), exec_state)?; + let major_radius = args.get_kw_arg_opt("majorRadius", &RuntimeType::num_any(), exec_state)?; + let major_diameter: Option = args.get_kw_arg_opt("majorDiameter", &RuntimeType::num_any(), exec_state)?; + let minor_radius = args.get_kw_arg_opt("minorRadius", &RuntimeType::num_any(), exec_state)?; + let minor_diameter: Option = args.get_kw_arg_opt("minorDiameter", &RuntimeType::num_any(), exec_state)?; + let major_radius = match (major_radius, major_diameter) { + (Some(_), Some(_)) | (None, None) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `majorDiameter` or `majorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (Some(major_radius), _) => major_radius, + (_, Some(major_diameter)) => TyF64 { + n: 0.5 * major_diameter.n, + ty: major_diameter.ty, + }, + }; + + let minor_radius = match (minor_radius, minor_diameter) { + (Some(_), Some(_)) | (None, None) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `minorDiameter` or `minorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (Some(minor_radius), _) => minor_radius, + (_, Some(minor_diameter)) => TyF64 { + n: 0.5 * minor_diameter.n, + ty: minor_diameter.ty, + }, + }; let elliptic_point = inner_elliptic_point(x, y, major_radius, minor_radius, &args).await?; args.make_kcl_val_from_point(elliptic_point, exec_state.length_unit().into()) @@ -1993,10 +2022,41 @@ pub async fn elliptic(exec_state: &mut ExecState, args: Args) -> Result = args.get_kw_arg_opt("majorDiameter", &RuntimeType::length(), exec_state)?; let major_axis = args.get_kw_arg_opt("majorAxis", &RuntimeType::point2d(), exec_state)?; - let minor_radius = args.get_kw_arg("minorRadius", &RuntimeType::length(), exec_state)?; + let minor_radius = args.get_kw_arg_opt("minorRadius", &RuntimeType::length(), exec_state)?; + let minor_diameter: Option = args.get_kw_arg_opt("minorDiameter", &RuntimeType::length(), exec_state)?; let tag = args.get_kw_arg_opt("tag", &RuntimeType::tag_decl(), exec_state)?; + let major_radius = match (major_radius, major_diameter) { + (Some(_), Some(_)) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `majorDiameter` or `majorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (None, None) => None, + (Some(major_radius), _) => Some(major_radius), + (_, Some(major_diameter)) => Some(TyF64 { + n: 0.5 * major_diameter.n, + ty: major_diameter.ty, + }), + }; + + let minor_radius = match (minor_radius, minor_diameter) { + (Some(_), Some(_)) | (None, None) => { + return Err(KclError::new_type(KclErrorDetails::new( + "Provide either `minorDiameter` or `minorRadius`, not both.".to_string(), + vec![args.source_range], + ))); + } + (Some(minor_radius), _) => minor_radius, + (_, Some(minor_diameter)) => TyF64 { + n: 0.5 * minor_diameter.n, + ty: minor_diameter.ty, + }, + }; + let new_sketch = inner_elliptic( sketch, center, @@ -2036,7 +2096,7 @@ pub(crate) async fn inner_elliptic( let major_axis = match (major_axis, major_radius) { (Some(_), Some(_)) | (None, None) => { return Err(KclError::new_type(KclErrorDetails::new( - "Provide either `majorAxis` or `majorRadius`.".to_string(), + "Provide either `majorAxis` or `majorRadius`, not both.".to_string(), vec![args.source_range], ))); } diff --git a/rust/kcl-lib/std/sketch.kcl b/rust/kcl-lib/std/sketch.kcl index 898340a687a..603d2c34d57 100644 --- a/rust/kcl-lib/std/sketch.kcl +++ b/rust/kcl-lib/std/sketch.kcl @@ -357,6 +357,12 @@ export fn circle( /// exampleSketch = startSketchOn(XY) /// |> ellipse(center = [0, 0], majorRadius = 50, minorRadius = 20) /// ``` +/// +/// ``` +/// @settings(experimentalFeatures = allow) +/// exampleSketch = startSketchOn(YZ) +/// |> ellipse(center = [10, 10], majorDiameter = 40, minorRadius = 10) +/// ``` @(impl = std_rust, experimental = true) export fn ellipse( /// Sketch to extend, or plane or surface to sketch on. @@ -364,10 +370,14 @@ export fn ellipse( /// The center of the ellipse. @(snippetArray = ["0", "0"]) center: Point2d, - /// The minor radius of the ellipse. - minorRadius: number(Length), - /// The major radius of the ellipse. Equivalent to majorAxis = [majorRadius, 0]. + /// The minor radius of the ellipse. Incompatible with `minorDiameter`. + minorRadius?: number(Length), + /// The minor diameter of the ellipse. Incompatible with `minorRadius`. + minorDiameter?: number(Length), + /// The major radius of the ellipse. Equivalent to majorAxis = [majorRadius, 0]. Incompatible with `majorDiameter`. majorRadius?: number(Length), + /// The major diameter of the ellipse. Equivalent to 2.0 * majorRadius. Incompatible with `majorRadius`. + majorDiameter?: number(Length), /// The major axis of the ellipse. majorAxis?: Point2d, /// Create a new tag which refers to this ellipse. @@ -2240,11 +2250,15 @@ export fn elliptic( /// Where along the ellptic should this segment end? @(includeInSnippet = true) angleEnd: number(Angle), - /// The minor radius, b, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. + /// The minor radius, b, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Incompatible with `minorDiameter`. @(includeInSnippet = true) - minorRadius: number(Length), - /// The major radius, a, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Equivalent to majorAxis = [majorRadius, 0]. + minorRadius?: number(Length), + /// The minor diameter of the elliptic equation. Incompatible with `minorRadius`. + minorDiameter?: number(Length), + /// The major radius, a, of the elliptic equation x^2 / a^2 + y^2 / b^2 = 1. Equivalent to majorAxis = [majorRadius, 0]. Incompatible with `majorDiameter`. majorRadius?: number(Length), + /// The major diameter of the elliptic equation. Incompatible with `majorRadius`. + majorDiameter?: number(Length), /// The major axis of the elliptic. @(includeInSnippet = true) majorAxis?: Point2d, @@ -2262,10 +2276,14 @@ export fn elliptic( ///``` @(impl = std_rust) export fn ellipticPoint( - /// The major radius, a, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. - majorRadius: number, - /// The minor radius, b, of the hyperbolic equation x^2 / a ^ 2 + y^2 / b^2 = 1. - minorRadius: number, + /// The major radius, a, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. Incompatible with `majorDiameter`. + majorRadius?: number, + /// The major diameter of the elliptic equation. Incompatible with `majorRadius`. + majorDiameter?: number, + /// The minor radius, b, of the elliptic equation x^2 / a ^ 2 + y^2 / b^2 = 1. Incompatible with `minorDiameter`. + minorRadius?: number, + /// The minor diameter of the elliptic equation. Incompatible with `minorRadius`. + minorDiameter?: number, /// The x value. Calculates y and returns (x, y). Incompatible with `y`. x?: number(Length), /// The y value. Calculates x and returns (x, y). Incompatible with `x`. diff --git a/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-ellipse1.png b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-ellipse1.png new file mode 100644 index 00000000000..45c216eb7ee Binary files /dev/null and b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-ellipse1.png differ diff --git a/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-hyperbolic0.png b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-hyperbolic0.png index fa23a443c20..35f573564c4 100644 Binary files a/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-hyperbolic0.png and b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-hyperbolic0.png differ diff --git a/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-parabolic0.png b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-parabolic0.png index fa23a443c20..35f573564c4 100644 Binary files a/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-parabolic0.png and b/rust/kcl-lib/tests/outputs/serial_test_example_fn_std-sketch-parabolic0.png differ