Kaynağa Gözat

Change correction point

Kevin Lee 6 ay önce
ebeveyn
işleme
5a27b88ba3
3 değiştirilmiş dosya ile 205 ekleme ve 209 silme
  1. 89 86
      src/ezcad/objects/ellipse.rs
  2. 33 39
      src/ezcad/objects/mod.rs
  3. 83 84
      src/ezcad/objects/rectangle.rs

+ 89 - 86
src/ezcad/objects/ellipse.rs

@@ -1,86 +1,89 @@
-use std::fmt::{Debug, Display};
-
-use binrw::{BinRead, BinWrite};
-use diff::Diff;
-use log::{debug, warn};
-
-use crate::{
-    field_of::FieldOf,
-    types::{Coordinate, ObjectType, F64, U32},
-};
-
-use super::{ObjectCore, ObjectModifier, Translate};
-
-#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
-#[diff(attr(
-    #[derive(Debug, PartialEq)]
-))]
-pub struct Ellipse {
-    pub core: ObjectCore,
-    #[brw(magic(8u32))] // Number of following fields in struct
-    pub clockwise: U32,
-    pub drawn_corner_a: FieldOf<Coordinate>,
-    pub drawn_corner_b: FieldOf<Coordinate>,
-    pub start_angle: F64, // Radians
-    pub end_angle: F64,   // Radians
-    pub modifier: ObjectModifier,
-    pub open_curve: U32,
-}
-
-impl Display for Ellipse {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let (origin, width, height) = self
-            .modifier
-            .corrected(*self.drawn_corner_a, *self.drawn_corner_b);
-
-        if format!("{}", origin) !=  format!("{}", *self.core.origin) {
-            warn!("Origin mismatch! Core: {}, Calculated: {}", *self.core.origin, origin);
-        }
-
-        write!(
-            f,
-            "{}, Origin: {}, Width: {:.2}, Height: {:.2}, Start Radian: {:.2}, End Radian: {:.2}, Open Curve: {}", 
-            self.core,
-            origin,
-            width,
-            height,
-                *self.start_angle,
-                *self.end_angle,
-                *self.open_curve != 0,
-        )?;
-        write!(f, "\n{:?}", self.modifier)?;
-        Ok(())
-    }
-}
-
-impl Default for Ellipse {
-    fn default() -> Self {
-        Self {
-            core: ObjectCore::default(ObjectType::Ellipse),
-            clockwise: 0.into(),
-            drawn_corner_a: Coordinate { x: 0.0, y: 0.0 }.into(),
-            drawn_corner_b: Coordinate { x: 0.0, y: 0.0 }.into(),
-            start_angle: 0.0.into(),
-            end_angle: 0.0.into(),
-            modifier: ObjectModifier::default(),
-            open_curve: 0.into(),
-        }
-    }
-}
-
-impl Translate for Ellipse {
-    fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
-        origin.map(|origin| {
-            let delta: Coordinate = origin - *self.core.origin;
-            self.modifier.move_relative(delta);
-        });
-        self.core.move_absolute(origin, z);
-    }
-
-    fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
-        delta.map(|delta| {
-            self.modifier.move_relative(delta);
-        });
-        self.core.move_relative(delta, z);
-    }
-}
+use std::fmt::{Debug, Display};
+
+use binrw::{BinRead, BinWrite};
+use diff::Diff;
+use log::warn;
+
+use crate::{
+    field_of::FieldOf,
+    types::{Coordinate, ObjectType, F64, U32},
+};
+
+use super::{ObjectCore, ObjectModifier, Translate};
+
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
+#[diff(attr(
+    #[derive(Debug, PartialEq)]
+))]
+pub struct Ellipse {
+    pub core: ObjectCore,
+    #[brw(magic(8u32))] // Number of following fields in struct
+    pub clockwise: U32,
+    pub drawn_corner_a: FieldOf<Coordinate>,
+    pub drawn_corner_b: FieldOf<Coordinate>,
+    pub start_angle: F64, // Radians
+    pub end_angle: F64,   // Radians
+    pub modifier: ObjectModifier,
+    pub open_curve: U32,
+}
+
+impl Display for Ellipse {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let (origin, width, height) = self
+            .modifier
+            .corrected(*self.drawn_corner_a, *self.drawn_corner_b);
+
+        if format!("{}", origin) != format!("{}", *self.core.origin) {
+            warn!(
+                "Origin mismatch! Core: {}, Calculated: {}",
+                *self.core.origin, origin
+            );
+        }
+
+        write!(
+            f,
+            "{}, Origin: {}, Width: {:.2}, Height: {:.2}, Start Radian: {:.2}, End Radian: {:.2}, Open Curve: {}", 
+            self.core,
+            origin,
+            width,
+            height,
+                *self.start_angle,
+                *self.end_angle,
+                *self.open_curve != 0,
+        )?;
+        write!(f, "\n{:?}", self.modifier)?;
+        Ok(())
+    }
+}
+
+impl Default for Ellipse {
+    fn default() -> Self {
+        Self {
+            core: ObjectCore::default(ObjectType::Ellipse),
+            clockwise: 0.into(),
+            drawn_corner_a: Coordinate { x: 0.0, y: 0.0 }.into(),
+            drawn_corner_b: Coordinate { x: 0.0, y: 0.0 }.into(),
+            start_angle: 0.0.into(),
+            end_angle: 0.0.into(),
+            modifier: ObjectModifier::default(),
+            open_curve: 0.into(),
+        }
+    }
+}
+
+impl Translate for Ellipse {
+    fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
+        origin.map(|origin| {
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
+        });
+        self.core.move_absolute(origin, z);
+    }
+
+    fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
+        delta.map(|delta| {
+            self.modifier.move_relative(delta);
+        });
+        self.core.move_relative(delta, z);
+    }
+}

+ 33 - 39
src/ezcad/objects/mod.rs

@@ -323,17 +323,8 @@ impl ObjectModifier {
             self.modifiers.y_skew.asin().to_degrees()
         );
 
-        // // Calculated unskewed width and height
-        // let Coordinate {
-        //     x: width,
-        //     y: height,
-        // } = (pt1.max(pt2) - pt1.min(pt2)) * self.scale();
-
-        // debug!("Drawn point 1: {}", pt1);
-        // debug!("Drawn point 2: {}", pt2);
-
-        // Calculate all 4 points of drawn rectangle
-        let points: Vec<Coordinate> = vec![
+        // Calculate 4 points of drawn rectangle
+        let drawn_pts: Vec<Coordinate> = vec![
             Coordinate {
                 x: pt1.min(pt2).x,
                 y: pt1.min(pt2).y,
@@ -354,24 +345,15 @@ impl ObjectModifier {
 
         debug!(
             "Drawn points: {}",
-            points
+            drawn_pts
                 .iter()
                 .map(|x| format!("{x}"))
                 .collect_vec()
                 .join(", ")
         );
 
-        // trace!("X skew asin tan: {:.3}", self.modifiers.x_skew.asin().tan());
-        // trace!("Y skew asin tan: {:.3}", self.modifiers.y_skew.asin().tan());
-
-        // let skew = |pt: Coordinate| -> Coordinate {
-        //     Coordinate {
-        //         x: pt.x + pt.y * self.modifiers.x_skew.asin().tan(),
-        //         y: pt.y + pt.x * self.modifiers.y_skew.asin().tan(),
-        //     }
-        // };
-
-        let skewed_points: Vec<Coordinate> = points
+        // Apply skew to 4 points of drawn rectangle
+        let skewed_pts: Vec<Coordinate> = drawn_pts
             .iter()
             .map(|pt| Coordinate {
                 x: pt.x + pt.y * self.modifiers.x_skew.asin().tan(),
@@ -381,36 +363,48 @@ impl ObjectModifier {
 
         debug!(
             "Skewed points: {}",
-            skewed_points
+            skewed_pts
                 .iter()
                 .map(|x| format!("{x}"))
                 .collect_vec()
                 .join(", ")
         );
 
-        let min_x: f64 = skewed_points.iter().fold(f64::MAX, |acc, pt| acc.min(pt.x));
-        let max_x: f64 = skewed_points.iter().fold(f64::MIN, |acc, pt| acc.max(pt.x));
-        let min_y: f64 = skewed_points.iter().fold(f64::MAX, |acc, pt| acc.min(pt.y));
-        let max_y: f64 = skewed_points.iter().fold(f64::MIN, |acc, pt| acc.max(pt.y));
-
-        let bounding_box_pts: (Coordinate, Coordinate) = (
-            Coordinate { x: min_x, y: min_y },
-            Coordinate { x: max_x, y: max_y },
-        );
+        // Apply correction
+        let corrected_pts: Vec<Coordinate> = skewed_pts
+            .iter()
+            .map(|pt| *pt * self.scale() + self.correction())
+            .collect_vec();
 
         debug!(
-            "Bounding box (scaled): {}, {}",
-            bounding_box_pts.0, bounding_box_pts.1
+            "Skewed points (corrected): {}",
+            corrected_pts
+                .iter()
+                .map(|x| format!("{x}"))
+                .collect_vec()
+                .join(", ")
         );
 
-        let origin: Coordinate = self.correction()
-            + self.scale() * (bounding_box_pts.0 + bounding_box_pts.1)
-                / Coordinate::from((2.0, 2.0));
+        // Calculate bounds
+        let min_x: f64 = corrected_pts.iter().fold(f64::MAX, |acc, pt| acc.min(pt.x));
+        let max_x: f64 = corrected_pts.iter().fold(f64::MIN, |acc, pt| acc.max(pt.x));
+        let min_y: f64 = corrected_pts.iter().fold(f64::MAX, |acc, pt| acc.min(pt.y));
+        let max_y: f64 = corrected_pts.iter().fold(f64::MIN, |acc, pt| acc.max(pt.y));
+
+        // Compute corrected min/max bounding box
+        let bound_a: Coordinate = Coordinate { x: min_x, y: min_y };
+        let bound_b: Coordinate = Coordinate { x: max_x, y: max_y };
+
+        debug!("Skewed bounding box (corrected): {}, {}", bound_a, bound_b);
+
+        // Calculate origin of bounding box
+        let origin: Coordinate = (bound_a + bound_b) / Coordinate::from((2.0, 2.0));
 
+        // Calculate width and height of bounding box
         let Coordinate {
             x: width,
             y: height,
-        } = (bounding_box_pts.1 - bounding_box_pts.0) * self.scale();
+        } = bound_b - bound_a;
 
         (origin, width, height)
     }

+ 83 - 84
src/ezcad/objects/rectangle.rs

@@ -1,84 +1,83 @@
-use std::fmt::{Debug, Display};
-
-use binrw::{BinRead, BinWrite};
-use diff::Diff;
-
-use crate::{
-    field_of::FieldOf,
-    types::{Coordinate, ObjectType, F64},
-};
-
-use super::{ObjectCore, ObjectModifier, Translate};
-
-#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
-#[diff(attr(
-    #[derive(Debug, PartialEq)]
-))]
-pub struct Rectangle {
-    pub core: ObjectCore,
-    #[brw(magic(8u32))] // Number of following fields in struct
-    pub drawn_corner_a: FieldOf<Coordinate>,
-    pub drawn_corner_b: FieldOf<Coordinate>,
-    pub round_bottom_left: F64,
-    pub round_bottom_right: F64,
-    pub round_top_right: F64,
-    pub round_top_left: F64,
-    pub modifier: ObjectModifier,
-}
-
-impl Display for Rectangle {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let width: f64 = (self.drawn_corner_a.x.max(self.drawn_corner_b.x)
-            - self.drawn_corner_a.x.min(self.drawn_corner_b.x))
-            * self.modifier.modifiers.x_scale;
-        let height: f64 = (self.drawn_corner_a.y.max(self.drawn_corner_b.y)
-            - self.drawn_corner_a.y.min(self.drawn_corner_b.y))
-            * self.modifier.modifiers.y_scale;
-
-        let drawn_origin: Coordinate =
-            (*self.drawn_corner_a + *self.drawn_corner_b) / Coordinate { x: 2.0, y: 2.0 };
-
-        write!(
-            f,
-            "{}, Origin: {}, Width: {:.2}, Height: {:.2}",
-            self.core,
-            self.modifier.correction() + drawn_origin * self.modifier.scale(),
-            width,
-            height,
-        )
-    }
-}
-
-impl Default for Rectangle {
-    fn default() -> Self {
-        Self {
-            core: ObjectCore::default(ObjectType::Rectangle),
-            drawn_corner_a: Coordinate { x: 0.0, y: 0.0 }.into(),
-            drawn_corner_b: Coordinate { x: 0.0, y: 0.0 }.into(),
-            round_bottom_left: 0.0.into(),
-            round_bottom_right: 0.0.into(),
-            round_top_right: 0.0.into(),
-            round_top_left: 0.0.into(),
-            modifier: ObjectModifier::default(),
-        }
-    }
-}
-
-// origin_x = x_corretion + (drawn_a.x + drawn_b.x) / 2 * x_scale
-// x_correction = origin_x - (drawn_a.x + drawn_b.x) / 2 * x_scale
-impl Translate for Rectangle {
-    fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
-        origin.map(|origin| {
-            let delta: Coordinate = origin - *self.core.origin;
-            self.modifier.move_relative(delta);
-        });
-        self.core.move_absolute(origin, z);
-    }
-
-    fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
-        delta.map(|delta| {
-            self.modifier.move_relative(delta);
-        });
-        self.core.move_relative(delta, z);
-    }
-}
+use std::fmt::{Debug, Display};
+
+use binrw::{BinRead, BinWrite};
+use diff::Diff;
+use log::warn;
+
+use crate::{
+    field_of::FieldOf,
+    types::{Coordinate, ObjectType, F64},
+};
+
+use super::{ObjectCore, ObjectModifier, Translate};
+
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
+#[diff(attr(
+    #[derive(Debug, PartialEq)]
+))]
+pub struct Rectangle {
+    pub core: ObjectCore,
+    #[brw(magic(8u32))] // Number of following fields in struct
+    pub drawn_corner_a: FieldOf<Coordinate>,
+    pub drawn_corner_b: FieldOf<Coordinate>,
+    pub round_bottom_left: F64,
+    pub round_bottom_right: F64,
+    pub round_top_right: F64,
+    pub round_top_left: F64,
+    pub modifier: ObjectModifier,
+}
+
+impl Display for Rectangle {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let (origin, width, height) = self
+            .modifier
+            .corrected(*self.drawn_corner_a, *self.drawn_corner_b);
+
+        if format!("{}", origin) != format!("{}", *self.core.origin) {
+            warn!(
+                "Origin mismatch! Core: {}, Calculated: {}",
+                *self.core.origin, origin
+            );
+        }
+
+        write!(
+            f,
+            "{}, Origin: {}, Width: {:.2}, Height: {:.2}",
+            self.core, origin, width, height,
+        )
+    }
+}
+
+impl Default for Rectangle {
+    fn default() -> Self {
+        Self {
+            core: ObjectCore::default(ObjectType::Rectangle),
+            drawn_corner_a: Coordinate { x: 0.0, y: 0.0 }.into(),
+            drawn_corner_b: Coordinate { x: 0.0, y: 0.0 }.into(),
+            round_bottom_left: 0.0.into(),
+            round_bottom_right: 0.0.into(),
+            round_top_right: 0.0.into(),
+            round_top_left: 0.0.into(),
+            modifier: ObjectModifier::default(),
+        }
+    }
+}
+
+// origin_x = x_corretion + (drawn_a.x + drawn_b.x) / 2 * x_scale
+// x_correction = origin_x - (drawn_a.x + drawn_b.x) / 2 * x_scale
+impl Translate for Rectangle {
+    fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
+        origin.map(|origin| {
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
+        });
+        self.core.move_absolute(origin, z);
+    }
+
+    fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
+        delta.map(|delta| {
+            self.modifier.move_relative(delta);
+        });
+        self.core.move_relative(delta, z);
+    }
+}