Compare commits
1 Commits
kcl-0.2.35
...
mike/secon
Author | SHA1 | Date | |
---|---|---|---|
828a53f215 |
@ -21,7 +21,7 @@ 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_start_center_and_end, get_tangent_point_from_previous_arc, get_tangential_arc_to_info,
|
||||||
get_x_component, get_y_component, intersection_with_parallel_line, TangentialArcInfoInput,
|
get_x_component, get_y_component, intersection_with_parallel_line, TangentialArcInfoInput,
|
||||||
},
|
},
|
||||||
Args,
|
Args,
|
||||||
@ -1485,6 +1485,17 @@ pub async fn arc(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch))
|
Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Squared distance between two points
|
||||||
|
fn distance_squared(a: Point2d, b: Point2d) -> f64 {
|
||||||
|
let v = Point2d {
|
||||||
|
x: b.x - a.x,
|
||||||
|
y: b.y - a.y,
|
||||||
|
};
|
||||||
|
let dot = v.x * v.x + v.y * v.y;
|
||||||
|
|
||||||
|
dot
|
||||||
|
}
|
||||||
|
|
||||||
/// Draw a curved line segment along an imaginary circle.
|
/// Draw a curved line segment along an imaginary circle.
|
||||||
/// The arc is constructed such that the current position of the sketch is
|
/// The arc is constructed such that the current position of the sketch is
|
||||||
/// placed along an imaginary circle of the specified radius, at angleStart
|
/// placed along an imaginary circle of the specified radius, at angleStart
|
||||||
@ -1524,9 +1535,31 @@ pub(crate) async fn inner_arc(
|
|||||||
angle_end,
|
angle_end,
|
||||||
radius,
|
radius,
|
||||||
} => {
|
} => {
|
||||||
let a_start = Angle::from_degrees(*angle_start);
|
let mut a_start = Angle::from_degrees(*angle_start);
|
||||||
let a_end = Angle::from_degrees(*angle_end);
|
let mut a_end = Angle::from_degrees(*angle_end);
|
||||||
let (center, end) = arc_center_and_end(from, a_start, a_end, *radius);
|
|
||||||
|
//duplicating engine logic to make sure this is _exactly_ what engine is doing - mike
|
||||||
|
// if a_start.to_degrees() > a_end.to_degrees() {
|
||||||
|
// // this implies a clockwise arc, so swap the angles to a matching counter-clockwise arc
|
||||||
|
// std::mem::swap(&mut a_start, &mut a_end);
|
||||||
|
// }
|
||||||
|
|
||||||
|
let (mut start, center, mut end) = arc_start_center_and_end(from, a_start, a_end, *radius);
|
||||||
|
let desired_start = from;
|
||||||
|
let dist1 = distance_squared(start, desired_start);
|
||||||
|
let dist2 = distance_squared(end, desired_start);
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
web_sys::console::log_1(&format!("testing {dist1} vs {dist2}!").into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(dist2 < dist1) { //flipped from engine ????????????
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
web_sys::console::log_1(&format!("swapping!").into());
|
||||||
|
std::mem::swap(&mut start, &mut end);
|
||||||
|
}
|
||||||
|
|
||||||
(center, a_start, a_end, *radius, end)
|
(center, a_start, a_end, *radius, end)
|
||||||
}
|
}
|
||||||
ArcData::CenterToRadius { center, to, radius } => {
|
ArcData::CenterToRadius { center, to, radius } => {
|
||||||
@ -1671,7 +1704,7 @@ async fn inner_tangential_arc(
|
|||||||
// but the above logic *should* capture that behavior
|
// but the above logic *should* capture that behavior
|
||||||
let start_angle = previous_end_tangent + tangent_to_arc_start_angle;
|
let start_angle = previous_end_tangent + tangent_to_arc_start_angle;
|
||||||
let end_angle = start_angle + offset;
|
let end_angle = start_angle + offset;
|
||||||
let (center, to) = arc_center_and_end(from, start_angle, end_angle, radius);
|
let (_, center, to) = arc_start_center_and_end(from, start_angle, end_angle, radius);
|
||||||
|
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
|
@ -204,21 +204,76 @@ pub fn get_x_component(angle: Angle, y: f64) -> Point2d {
|
|||||||
Point2d { x, y }.scale(sign)
|
Point2d { x, y }.scale(sign)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arc_center_and_end(from: Point2d, start_angle: Angle, end_angle: Angle, radius: f64) -> (Point2d, Point2d) {
|
fn arc_center_and_end(from: Point2d, start_angle: Angle, end_angle: Angle, radius: f64) -> (Point2d, Point2d) {
|
||||||
|
let (_, center, end) = arc_start_center_and_end(from, start_angle, end_angle, radius);
|
||||||
|
(center, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arc_start_center_and_end(from: Point2d, start_angle: Angle, end_angle: Angle, radius: f64) -> (Point2d, Point2d, Point2d) {
|
||||||
let start_angle = start_angle.to_radians();
|
let start_angle = start_angle.to_radians();
|
||||||
let end_angle = end_angle.to_radians();
|
let end_angle = end_angle.to_radians();
|
||||||
|
|
||||||
|
let eval = |t: f64, radius: f64, center: Point2d| { //UNUSED (this didn't work either for some reason.. - mike)
|
||||||
|
//HACK - using this as an example to demonstrate that even something as simple as an arc can be problematic to
|
||||||
|
//duplicate this type of logic on the frontend side because of all the little edge cases
|
||||||
|
//we must come up with a better strategy to avoid this sort of stuff in the future.
|
||||||
|
//having to manually port this sort of code directly into rust is error-prone, and
|
||||||
|
//really isn't a good usage of dev time - mike
|
||||||
|
let sin_of_pi = if ((4.0*PI).sin()).abs() > PI.sin().abs() {
|
||||||
|
4.0*PI.sin().abs()
|
||||||
|
} else {
|
||||||
|
PI.sin().abs()
|
||||||
|
};
|
||||||
|
|
||||||
|
let cos_of_pi_over_2 = if (4.5*PI).cos().abs() > (0.5*PI).sin().abs() {
|
||||||
|
(4.5*PI).cos().abs()
|
||||||
|
} else {
|
||||||
|
(0.5*PI).sin().abs()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c = t.cos();
|
||||||
|
let mut s = t.sin();
|
||||||
|
|
||||||
|
if c.abs() <= cos_of_pi_over_2 {
|
||||||
|
c = 0.0;
|
||||||
|
s = if s < 0.0 { -1.0 } else { 1.0 };
|
||||||
|
} else if s.abs() <= sin_of_pi {
|
||||||
|
s = 0.0;
|
||||||
|
c = if c < 0.0 { -1.0 } else { 1.0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2d {
|
||||||
|
x: center.x + radius * c,
|
||||||
|
y: center.y + radius * s,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let center = Point2d {
|
let center = Point2d {
|
||||||
x: -1.0 * (radius * start_angle.cos() - from.x),
|
x: -1.0 * (radius * start_angle.cos() - from.x),
|
||||||
y: -1.0 * (radius * start_angle.sin() - from.y),
|
y: -1.0 * (radius * start_angle.sin() - from.y),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//let start = eval(start_angle, radius, center);
|
||||||
|
//let end = eval(end_angle, radius, center);
|
||||||
|
|
||||||
|
let start = Point2d {
|
||||||
|
x: center.x + radius * start_angle.cos(),
|
||||||
|
y: center.y + radius * start_angle.sin(),
|
||||||
|
};
|
||||||
|
|
||||||
let end = Point2d {
|
let end = Point2d {
|
||||||
x: center.x + radius * end_angle.cos(),
|
x: center.x + radius * end_angle.cos(),
|
||||||
y: center.y + radius * end_angle.sin(),
|
y: center.y + radius * end_angle.sin(),
|
||||||
};
|
};
|
||||||
|
|
||||||
(center, end)
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
let start_deg = start_angle.to_degrees();
|
||||||
|
let end_deg = end_angle.to_degrees();
|
||||||
|
web_sys::console::log_1(&format!("Arc testing {start_deg:?}, {end_deg:?} -> center: {center:?}, start: {start:?} end: {end:?}").into());
|
||||||
|
}
|
||||||
|
|
||||||
|
(start, center, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arc_angles(
|
pub fn arc_angles(
|
||||||
|
Reference in New Issue
Block a user