Add tangentToEnd stdlib function (#4541)
This commit is contained in:
@ -102,6 +102,7 @@ layout: manual
|
|||||||
* [`startSketchAt`](kcl/startSketchAt)
|
* [`startSketchAt`](kcl/startSketchAt)
|
||||||
* [`startSketchOn`](kcl/startSketchOn)
|
* [`startSketchOn`](kcl/startSketchOn)
|
||||||
* [`tan`](kcl/tan)
|
* [`tan`](kcl/tan)
|
||||||
|
* [`tangentToEnd`](kcl/tangentToEnd)
|
||||||
* [`tangentialArc`](kcl/tangentialArc)
|
* [`tangentialArc`](kcl/tangentialArc)
|
||||||
* [`tangentialArcTo`](kcl/tangentialArcTo)
|
* [`tangentialArcTo`](kcl/tangentialArcTo)
|
||||||
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
|
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
|
||||||
|
1915
docs/kcl/std.json
1915
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
105
docs/kcl/tangentToEnd.md
Normal file
105
docs/kcl/tangentToEnd.md
Normal file
File diff suppressed because one or more lines are too long
@ -91,7 +91,7 @@ a complete arc
|
|||||||
| `type` |enum: `Circle`| | No |
|
| `type` |enum: `Circle`| | No |
|
||||||
| `center` |`[number, number]`| the arc's center | No |
|
| `center` |`[number, number]`| the arc's center | No |
|
||||||
| `radius` |`number`| the arc's radius | No |
|
| `radius` |`number`| the arc's radius | No |
|
||||||
| `ccw` |`boolean`| arc's direction | No |
|
| `ccw` |`boolean`| arc's direction This is used to compute the tangential angle. | No |
|
||||||
| `from` |`[number, number]`| The from point. | No |
|
| `from` |`[number, number]`| The from point. | No |
|
||||||
| `to` |`[number, number]`| The to point. | No |
|
| `to` |`[number, number]`| The to point. | No |
|
||||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||||
@ -177,6 +177,7 @@ A circular arc, not necessarily tangential to the current point.
|
|||||||
| `type` |enum: `Arc`| | No |
|
| `type` |enum: `Arc`| | No |
|
||||||
| `center` |`[number, number]`| Center of the circle that this arc is drawn on. | No |
|
| `center` |`[number, number]`| Center of the circle that this arc is drawn on. | No |
|
||||||
| `radius` |`number`| Radius of the circle that this arc is drawn on. | No |
|
| `radius` |`number`| Radius of the circle that this arc is drawn on. | No |
|
||||||
|
| `ccw` |`boolean`| True if the arc is counterclockwise. | No |
|
||||||
| `from` |`[number, number]`| The from point. | No |
|
| `from` |`[number, number]`| The from point. | No |
|
||||||
| `to` |`[number, number]`| The to point. | No |
|
| `to` |`[number, number]`| The to point. | No |
|
||||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||||
|
@ -824,10 +824,27 @@ impl SketchSurface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GetTangentialInfoFromPathsResult {
|
#[derive(Debug, Clone)]
|
||||||
pub center_or_tangent_point: [f64; 2],
|
pub(crate) enum GetTangentialInfoFromPathsResult {
|
||||||
pub is_center: bool,
|
PreviousPoint([f64; 2]),
|
||||||
pub ccw: bool,
|
Arc { center: [f64; 2], ccw: bool },
|
||||||
|
Circle { center: [f64; 2], ccw: bool, radius: f64 },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetTangentialInfoFromPathsResult {
|
||||||
|
pub(crate) fn tan_previous_point(&self, last_arc_end: crate::std::utils::Coords2d) -> [f64; 2] {
|
||||||
|
match self {
|
||||||
|
GetTangentialInfoFromPathsResult::PreviousPoint(p) => *p,
|
||||||
|
GetTangentialInfoFromPathsResult::Arc { center, ccw, .. } => {
|
||||||
|
crate::std::utils::get_tangent_point_from_previous_arc(*center, *ccw, last_arc_end)
|
||||||
|
}
|
||||||
|
// The circle always starts at 0 degrees, so a suitable tangent
|
||||||
|
// point is either directly above or below.
|
||||||
|
GetTangentialInfoFromPathsResult::Circle {
|
||||||
|
center, radius, ccw, ..
|
||||||
|
} => [center[0] + radius, center[1] + if *ccw { -1.0 } else { 1.0 }],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sketch {
|
impl Sketch {
|
||||||
@ -863,32 +880,9 @@ impl Sketch {
|
|||||||
|
|
||||||
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
|
pub(crate) fn get_tangential_info_from_paths(&self) -> GetTangentialInfoFromPathsResult {
|
||||||
let Some(path) = self.latest_path() else {
|
let Some(path) = self.latest_path() else {
|
||||||
return GetTangentialInfoFromPathsResult {
|
return GetTangentialInfoFromPathsResult::PreviousPoint(self.start.to);
|
||||||
center_or_tangent_point: self.start.to,
|
|
||||||
is_center: false,
|
|
||||||
ccw: false,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
match path {
|
path.get_tangential_info()
|
||||||
Path::TangentialArc { center, ccw, .. } => GetTangentialInfoFromPathsResult {
|
|
||||||
center_or_tangent_point: *center,
|
|
||||||
is_center: true,
|
|
||||||
ccw: *ccw,
|
|
||||||
},
|
|
||||||
Path::TangentialArcTo { center, ccw, .. } => GetTangentialInfoFromPathsResult {
|
|
||||||
center_or_tangent_point: *center,
|
|
||||||
is_center: true,
|
|
||||||
ccw: *ccw,
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
let base = path.get_base();
|
|
||||||
GetTangentialInfoFromPathsResult {
|
|
||||||
center_or_tangent_point: base.from,
|
|
||||||
is_center: false,
|
|
||||||
ccw: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,7 +1269,7 @@ pub enum Path {
|
|||||||
/// the arc's radius
|
/// the arc's radius
|
||||||
radius: f64,
|
radius: f64,
|
||||||
/// arc's direction
|
/// arc's direction
|
||||||
// Maybe this one's not needed since it's a full revolution?
|
/// This is used to compute the tangential angle.
|
||||||
ccw: bool,
|
ccw: bool,
|
||||||
},
|
},
|
||||||
/// A path that is horizontal.
|
/// A path that is horizontal.
|
||||||
@ -1307,6 +1301,8 @@ pub enum Path {
|
|||||||
center: [f64; 2],
|
center: [f64; 2],
|
||||||
/// Radius of the circle that this arc is drawn on.
|
/// Radius of the circle that this arc is drawn on.
|
||||||
radius: f64,
|
radius: f64,
|
||||||
|
/// True if the arc is counterclockwise.
|
||||||
|
ccw: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1430,6 +1426,28 @@ impl Path {
|
|||||||
Path::Arc { base, .. } => Some(base),
|
Path::Arc { base, .. } => Some(base),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_tangential_info(&self) -> GetTangentialInfoFromPathsResult {
|
||||||
|
match self {
|
||||||
|
Path::TangentialArc { center, ccw, .. }
|
||||||
|
| Path::TangentialArcTo { center, ccw, .. }
|
||||||
|
| Path::Arc { center, ccw, .. } => GetTangentialInfoFromPathsResult::Arc {
|
||||||
|
center: *center,
|
||||||
|
ccw: *ccw,
|
||||||
|
},
|
||||||
|
Path::Circle {
|
||||||
|
center, ccw, radius, ..
|
||||||
|
} => GetTangentialInfoFromPathsResult::Circle {
|
||||||
|
center: *center,
|
||||||
|
ccw: *ccw,
|
||||||
|
radius: *radius,
|
||||||
|
},
|
||||||
|
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {
|
||||||
|
let base = self.get_base();
|
||||||
|
GetTangentialInfoFromPathsResult::PreviousPoint(base.from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the straight-line distance between a pair of (2D) points.
|
/// Compute the straight-line distance between a pair of (2D) points.
|
||||||
|
@ -65,6 +65,7 @@ lazy_static! {
|
|||||||
Box::new(crate::std::segment::LastSegY),
|
Box::new(crate::std::segment::LastSegY),
|
||||||
Box::new(crate::std::segment::SegLen),
|
Box::new(crate::std::segment::SegLen),
|
||||||
Box::new(crate::std::segment::SegAng),
|
Box::new(crate::std::segment::SegAng),
|
||||||
|
Box::new(crate::std::segment::TangentToEnd),
|
||||||
Box::new(crate::std::segment::AngleToMatchLengthX),
|
Box::new(crate::std::segment::AngleToMatchLengthX),
|
||||||
Box::new(crate::std::segment::AngleToMatchLengthY),
|
Box::new(crate::std::segment::AngleToMatchLengthY),
|
||||||
Box::new(crate::std::shapes::Circle),
|
Box::new(crate::std::shapes::Circle),
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
|
use kittycad_modeling_cmds::shared::Angle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
executor::{ExecState, KclValue, Sketch, TagIdentifier},
|
executor::{ExecState, KclValue, Point2d, Sketch, TagIdentifier},
|
||||||
std::{utils::between, Args},
|
std::{utils::between, Args},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -411,6 +412,112 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
|||||||
Ok(result.to_degrees())
|
Ok(result.to_degrees())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the angle coming out of the end of the segment in degrees.
|
||||||
|
pub async fn tangent_to_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
|
let tag: TagIdentifier = args.get_data()?;
|
||||||
|
|
||||||
|
let result = inner_tangent_to_end(&tag, exec_state, args.clone()).await?;
|
||||||
|
Ok(args.make_user_val_from_f64(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the angle coming out of the end of the segment in degrees.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// // Horizontal pill.
|
||||||
|
/// pillSketch = startSketchOn('XZ')
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> line([20, 0], %)
|
||||||
|
/// |> tangentialArcToRelative([0, 10], %, $arc1)
|
||||||
|
/// |> angledLine({
|
||||||
|
/// angle: tangentToEnd(arc1),
|
||||||
|
/// length: 20,
|
||||||
|
/// }, %)
|
||||||
|
/// |> tangentialArcToRelative([0, -10], %)
|
||||||
|
/// |> close(%)
|
||||||
|
///
|
||||||
|
/// pillExtrude = extrude(10, pillSketch)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// // Vertical pill. Use absolute coordinate for arc.
|
||||||
|
/// pillSketch = startSketchOn('XZ')
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> line([0, 20], %)
|
||||||
|
/// |> tangentialArcTo([10, 20], %, $arc1)
|
||||||
|
/// |> angledLine({
|
||||||
|
/// angle: tangentToEnd(arc1),
|
||||||
|
/// length: 20,
|
||||||
|
/// }, %)
|
||||||
|
/// |> tangentialArcToRelative([-10, 0], %)
|
||||||
|
/// |> close(%)
|
||||||
|
///
|
||||||
|
/// pillExtrude = extrude(10, pillSketch)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// rectangleSketch = startSketchOn('XZ')
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> line([10, 0], %, $seg1)
|
||||||
|
/// |> angledLine({
|
||||||
|
/// angle: tangentToEnd(seg1),
|
||||||
|
/// length: 10,
|
||||||
|
/// }, %)
|
||||||
|
/// |> line([0, 10], %)
|
||||||
|
/// |> line([-20, 0], %)
|
||||||
|
/// |> close(%)
|
||||||
|
///
|
||||||
|
/// rectangleExtrude = extrude(10, rectangleSketch)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// bottom = startSketchOn("XY")
|
||||||
|
/// |> startProfileAt([0, 0], %)
|
||||||
|
/// |> arcTo({
|
||||||
|
/// end: [10, 10],
|
||||||
|
/// interior: [5, 1]
|
||||||
|
/// }, %, $arc1)
|
||||||
|
/// |> angledLine([tangentToEnd(arc1), 20], %)
|
||||||
|
/// |> close(%)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// circSketch = startSketchOn("XY")
|
||||||
|
/// |> circle({ center: [0, 0], radius: 3 }, %, $circ)
|
||||||
|
///
|
||||||
|
/// triangleSketch = startSketchOn("XY")
|
||||||
|
/// |> startProfileAt([-5, 0], %)
|
||||||
|
/// |> angledLine([tangentToEnd(circ), 10], %)
|
||||||
|
/// |> line([-15, 0], %)
|
||||||
|
/// |> close(%)
|
||||||
|
/// ```
|
||||||
|
#[stdlib {
|
||||||
|
name = "tangentToEnd",
|
||||||
|
}]
|
||||||
|
async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
|
||||||
|
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||||
|
let path = line.path.clone().ok_or_else(|| {
|
||||||
|
KclError::Type(KclErrorDetails {
|
||||||
|
message: format!("Expected a line segment with a path, found `{:?}`", line),
|
||||||
|
source_ranges: vec![args.source_range],
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let from = Point2d::from(path.get_to());
|
||||||
|
|
||||||
|
// Undocumented voodoo from get_tangential_arc_to_info
|
||||||
|
let tangent_info = path.get_tangential_info();
|
||||||
|
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||||
|
|
||||||
|
// Calculate the end point from the angle and radius.
|
||||||
|
// atan2 outputs radians.
|
||||||
|
let previous_end_tangent = Angle::from_radians(f64::atan2(
|
||||||
|
from.y - tan_previous_point[1],
|
||||||
|
from.x - tan_previous_point[0],
|
||||||
|
));
|
||||||
|
|
||||||
|
Ok(previous_end_tangent.to_degrees())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the angle to match the given length for x.
|
/// Returns the angle to match the given length for x.
|
||||||
pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn angle_to_match_length_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
let (tag, to, sketch) = args.get_tag_to_number_sketch()?;
|
||||||
|
@ -97,6 +97,7 @@ async fn inner_circle(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let from = [data.center[0] + data.radius, data.center[1]];
|
||||||
let angle_start = Angle::zero();
|
let angle_start = Angle::zero();
|
||||||
let angle_end = Angle::turn();
|
let angle_end = Angle::turn();
|
||||||
|
|
||||||
@ -119,8 +120,8 @@ async fn inner_circle(
|
|||||||
|
|
||||||
let current_path = Path::Circle {
|
let current_path = Path::Circle {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: data.center,
|
from,
|
||||||
to: data.center,
|
to: from,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id,
|
id,
|
||||||
|
@ -21,8 +21,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
utils::{
|
utils::{
|
||||||
arc_angles, arc_center_and_end, get_tangent_point_from_previous_arc, get_tangential_arc_to_info,
|
arc_angles, arc_center_and_end, get_tangential_arc_to_info, get_x_component, get_y_component,
|
||||||
get_x_component, get_y_component, intersection_with_parallel_line, TangentialArcInfoInput,
|
intersection_with_parallel_line, TangentialArcInfoInput,
|
||||||
},
|
},
|
||||||
Args,
|
Args,
|
||||||
},
|
},
|
||||||
@ -1564,6 +1564,7 @@ pub(crate) async fn inner_arc(
|
|||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
let ccw = angle_start.to_degrees() < angle_end.to_degrees();
|
||||||
|
|
||||||
let id = exec_state.id_generator.next_uuid();
|
let id = exec_state.id_generator.next_uuid();
|
||||||
|
|
||||||
@ -1594,6 +1595,7 @@ pub(crate) async fn inner_arc(
|
|||||||
},
|
},
|
||||||
center: center.into(),
|
center: center.into(),
|
||||||
radius,
|
radius,
|
||||||
|
ccw,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_sketch = sketch.clone();
|
let mut new_sketch = sketch.clone();
|
||||||
@ -1668,8 +1670,8 @@ pub(crate) async fn inner_arc_to(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let start = [from.x, from.y];
|
let start = [from.x, from.y];
|
||||||
let interior = [data.interior[0], data.interior[1]];
|
let interior = data.interior;
|
||||||
let end = [data.end[0], data.end[1]];
|
let end = data.end;
|
||||||
|
|
||||||
// compute the center of the circle since we do not have the value returned from the engine
|
// compute the center of the circle since we do not have the value returned from the engine
|
||||||
let center = calculate_circle_center(start, interior, end);
|
let center = calculate_circle_center(start, interior, end);
|
||||||
@ -1680,6 +1682,8 @@ pub(crate) async fn inner_arc_to(
|
|||||||
(center[0] - start[0] * center[0] - start[0]) + (center[1] - start[1] * center[1] - start[1]);
|
(center[0] - start[0] * center[0] - start[0]) + (center[1] - start[1] * center[1] - start[1]);
|
||||||
let radius = sum_of_square_differences.sqrt();
|
let radius = sum_of_square_differences.sqrt();
|
||||||
|
|
||||||
|
let ccw = is_ccw(start, interior, end);
|
||||||
|
|
||||||
let current_path = Path::Arc {
|
let current_path = Path::Arc {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.into(),
|
||||||
@ -1692,6 +1696,7 @@ pub(crate) async fn inner_arc_to(
|
|||||||
},
|
},
|
||||||
center,
|
center,
|
||||||
radius,
|
radius,
|
||||||
|
ccw,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_sketch = sketch.clone();
|
let mut new_sketch = sketch.clone();
|
||||||
@ -1704,6 +1709,26 @@ pub(crate) async fn inner_arc_to(
|
|||||||
Ok(new_sketch)
|
Ok(new_sketch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the three-point arc is counterclockwise. The order of
|
||||||
|
/// parameters is critical.
|
||||||
|
///
|
||||||
|
/// | end
|
||||||
|
/// | /
|
||||||
|
/// | | / interior
|
||||||
|
/// | / /
|
||||||
|
/// | | /
|
||||||
|
/// |/_____________
|
||||||
|
/// start
|
||||||
|
///
|
||||||
|
/// If the slope of the line from start to interior is less than the slope of
|
||||||
|
/// the line from start to end, the arc is counterclockwise.
|
||||||
|
fn is_ccw(start: [f64; 2], interior: [f64; 2], end: [f64; 2]) -> bool {
|
||||||
|
let t1 = (interior[0] - start[0]) * (end[1] - start[1]);
|
||||||
|
let t2 = (end[0] - start[0]) * (interior[1] - start[1]);
|
||||||
|
// If these terms are equal, the points are collinear.
|
||||||
|
t1 > t2
|
||||||
|
}
|
||||||
|
|
||||||
/// Data to draw a tangential arc.
|
/// Data to draw a tangential arc.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
@ -1764,11 +1789,7 @@ async fn inner_tangential_arc(
|
|||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
// next set of lines is some undocumented voodoo from get_tangential_arc_to_info
|
||||||
let tangent_info = sketch.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
let tangent_info = sketch.get_tangential_info_from_paths(); //this function desperately needs some documentation
|
||||||
let tan_previous_point = if tangent_info.is_center {
|
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||||
get_tangent_point_from_previous_arc(tangent_info.center_or_tangent_point, tangent_info.ccw, from.into())
|
|
||||||
} else {
|
|
||||||
tangent_info.center_or_tangent_point
|
|
||||||
};
|
|
||||||
|
|
||||||
let id = exec_state.id_generator.next_uuid();
|
let id = exec_state.id_generator.next_uuid();
|
||||||
|
|
||||||
@ -1897,11 +1918,7 @@ async fn inner_tangential_arc_to(
|
|||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
let tangent_info = sketch.get_tangential_info_from_paths();
|
let tangent_info = sketch.get_tangential_info_from_paths();
|
||||||
let tan_previous_point = if tangent_info.is_center {
|
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||||
get_tangent_point_from_previous_arc(tangent_info.center_or_tangent_point, tangent_info.ccw, from.into())
|
|
||||||
} else {
|
|
||||||
tangent_info.center_or_tangent_point
|
|
||||||
};
|
|
||||||
let [to_x, to_y] = to;
|
let [to_x, to_y] = to;
|
||||||
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
||||||
arc_start_point: [from.x, from.y],
|
arc_start_point: [from.x, from.y],
|
||||||
@ -1966,12 +1983,10 @@ async fn inner_tangential_arc_to_relative(
|
|||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Sketch, KclError> {
|
) -> Result<Sketch, KclError> {
|
||||||
let from: Point2d = sketch.current_pen_position()?;
|
let from: Point2d = sketch.current_pen_position()?;
|
||||||
|
let to = [from.x + delta[0], from.y + delta[1]];
|
||||||
let tangent_info = sketch.get_tangential_info_from_paths();
|
let tangent_info = sketch.get_tangential_info_from_paths();
|
||||||
let tan_previous_point = if tangent_info.is_center {
|
let tan_previous_point = tangent_info.tan_previous_point(from.into());
|
||||||
get_tangent_point_from_previous_arc(tangent_info.center_or_tangent_point, tangent_info.ccw, from.into())
|
|
||||||
} else {
|
|
||||||
tangent_info.center_or_tangent_point
|
|
||||||
};
|
|
||||||
let [dx, dy] = delta;
|
let [dx, dy] = delta;
|
||||||
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
||||||
arc_start_point: [from.x, from.y],
|
arc_start_point: [from.x, from.y],
|
||||||
@ -2002,7 +2017,7 @@ async fn inner_tangential_arc_to_relative(
|
|||||||
let current_path = Path::TangentialArcTo {
|
let current_path = Path::TangentialArcTo {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
from: from.into(),
|
from: from.into(),
|
||||||
to: delta,
|
to,
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
geo_meta: GeoMeta {
|
geo_meta: GeoMeta {
|
||||||
id,
|
id,
|
||||||
|
@ -64,13 +64,13 @@ snapshot_kind: text
|
|||||||
5.0
|
5.0
|
||||||
],
|
],
|
||||||
"from": [
|
"from": [
|
||||||
5.0,
|
15.0,
|
||||||
5.0
|
5.0
|
||||||
],
|
],
|
||||||
"radius": 10.0,
|
"radius": 10.0,
|
||||||
"tag": null,
|
"tag": null,
|
||||||
"to": [
|
"to": [
|
||||||
5.0,
|
15.0,
|
||||||
5.0
|
5.0
|
||||||
],
|
],
|
||||||
"type": "Circle"
|
"type": "Circle"
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -105,6 +105,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
200.0,
|
200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -288,6 +289,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
-200.0,
|
-200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -775,6 +777,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
-200.0,
|
-200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -850,6 +853,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
200.0,
|
200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -1337,6 +1341,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
200.0,
|
200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -2779,6 +2784,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
200.0,
|
200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -3266,6 +3272,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
200.0,
|
200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -3389,6 +3396,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
-200.0,
|
-200.0,
|
||||||
100.0
|
100.0
|
||||||
@ -3876,6 +3884,7 @@ snapshot_kind: text
|
|||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ccw": true,
|
||||||
"center": [
|
"center": [
|
||||||
-200.0,
|
-200.0,
|
||||||
100.0
|
100.0
|
||||||
|
@ -373,7 +373,7 @@ snapshot_kind: text
|
|||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"from": [
|
"from": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"radius": 5.0,
|
"radius": 5.0,
|
||||||
@ -384,7 +384,7 @@ snapshot_kind: text
|
|||||||
"value": "myCircle"
|
"value": "myCircle"
|
||||||
},
|
},
|
||||||
"to": [
|
"to": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"type": "Circle"
|
"type": "Circle"
|
||||||
@ -660,7 +660,7 @@ snapshot_kind: text
|
|||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"from": [
|
"from": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"radius": 5.0,
|
"radius": 5.0,
|
||||||
@ -671,7 +671,7 @@ snapshot_kind: text
|
|||||||
"value": "myCircle"
|
"value": "myCircle"
|
||||||
},
|
},
|
||||||
"to": [
|
"to": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"type": "Circle"
|
"type": "Circle"
|
||||||
@ -950,7 +950,7 @@ snapshot_kind: text
|
|||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"from": [
|
"from": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"radius": 5.0,
|
"radius": 5.0,
|
||||||
@ -961,7 +961,7 @@ snapshot_kind: text
|
|||||||
"value": "myCircle"
|
"value": "myCircle"
|
||||||
},
|
},
|
||||||
"to": [
|
"to": [
|
||||||
0.0,
|
5.0,
|
||||||
0.0
|
0.0
|
||||||
],
|
],
|
||||||
"type": "Circle"
|
"type": "Circle"
|
||||||
|
Reference in New Issue
Block a user