Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_geom/src/shape.rs

5.0 KiB, 8 runs

created by r1870400018:9167, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use std::f32::consts::PI as PI32;
2use std::f64::consts::PI as PI64;
3
4/// A shape with f32 dimensions supporting area and perimeter calculations.
5#[derive(Clone, Copy, Debug)]
6pub enum ShapeF32 {
7 Circle(f32),
8 Rectangle(f32, f32),
9 Square(f32),
10}
11
12impl ShapeF32 {
13 /// Calculates the area of the shape.
14 ///
15 /// # Returns
16 /// The area as an f32 value.
17 pub fn area(&self) -> f32 {
18 match self {
19 Self::Circle(r) => PI32 * r * r,
20 Self::Rectangle(w, h) => w * h,
21 Self::Square(s) => s * s,
22 }
23 }
24
25 /// Calculates the perimeter of the shape.
26 ///
27 /// # Returns
28 /// The perimeter as an f32 value.
29 pub fn perimeter(&self) -> f32 {
30 match self {
31 Self::Circle(r) => 2.0 * PI32 * r,
32 Self::Rectangle(w, h) => 2.0 * (w + h),
33 Self::Square(s) => 4.0 * s,
34 }
35 }
36
37 /// Scales the shape by an area factor while preserving aspect ratio.
38 ///
39 /// # Arguments
40 /// * `factor` - The area scaling factor (e.g., 2.0 doubles the area).
41 ///
42 /// # Returns
43 /// A new shape with scaled dimensions.
44 pub fn scale_by_area(&self, factor: f32) -> Self {
45 let scale = factor.sqrt(); // Linear scale factor.
46 match self {
47 Self::Circle(r) => Self::Circle(r * scale),
48 Self::Rectangle(w, h) => Self::Rectangle(w * scale, h * scale),
49 Self::Square(s) => Self::Square(s * scale),
50 }
51 }
52}
53
54/// A shape with f64 dimensions supporting area and perimeter calculations.
55#[derive(Clone, Copy, Debug)]
56pub enum ShapeF64 {
57 Circle(f64),
58 Rectangle(f64, f64),
59 Square(f64),
60}
61
62impl ShapeF64 {
63 /// Calculates the area of the shape.
64 ///
65 /// # Returns
66 /// The area as an f64 value.
67 pub fn area(&self) -> f64 {
68 match self {
69 Self::Circle(r) => PI64 * r * r,
70 Self::Rectangle(w, h) => w * h,
71 Self::Square(s) => s * s,
72 }
73 }
74
75 /// Calculates the perimeter of the shape.
76 ///
77 /// # Returns
78 /// The perimeter as an f64 value.
79 pub fn perimeter(&self) -> f64 {
80 match self {
81 Self::Circle(r) => 2.0 * PI64 * r,
82 Self::Rectangle(w, h) => 2.0 * (w + h),
83 Self::Square(s) => 4.0 * s,
84 }
85 }
86
87 /// Scales the shape by an area factor while preserving aspect ratio.
88 ///
89 /// # Arguments
90 /// * `factor` - The area scaling factor (e.g., 2.0 doubles the area).
91 ///
92 /// # Returns
93 /// A new shape with scaled dimensions.
94 pub fn scale_by_area(&self, factor: f64) -> Self {
95 let scale = factor.sqrt(); // Linear scale factor.
96 match self {
97 Self::Circle(r) => Self::Circle(r * scale),
98 Self::Rectangle(w, h) => Self::Rectangle(w * scale, h * scale),
99 Self::Square(s) => Self::Square(s * scale),
100 }
101 }
102}
103
104/// A shape with u32 dimensions supporting area and perimeter calculations.
105///
106/// Note: Circle calculations use integer approximations.
107#[derive(Clone, Copy, Debug)]
108pub enum ShapeU32 {
109 Circle(u32),
110 Rectangle(u32, u32),
111 Square(u32),
112}
113
114impl ShapeU32 {
115 /// Calculates the area of the shape.
116 ///
117 /// For circles, uses integer approximation with PI ≈ 355/113.
118 ///
119 /// # Returns
120 /// The area as a u32 value.
121 pub fn area(&self) -> u32 {
122 match self {
123 Self::Circle(r) => {
124 // Using PI approximation 355/113 for integer arithmetic.
125 let r_u64 = *r as u64;
126 ((355 * r_u64 * r_u64) / 113) as u32
127 },
128 Self::Rectangle(w, h) => w * h,
129 Self::Square(s) => s * s,
130 }
131 }
132
133 /// Calculates the perimeter of the shape.
134 ///
135 /// For circles, uses integer approximation with PI ≈ 355/113.
136 ///
137 /// # Returns
138 /// The perimeter as a u32 value.
139 pub fn perimeter(&self) -> u32 {
140 match self {
141 Self::Circle(r) => {
142 // Using PI approximation 355/113 for integer arithmetic.
143 let r_u64 = *r as u64;
144 ((2 * 355 * r_u64) / 113) as u32
145 },
146 Self::Rectangle(w, h) => 2 * (w + h),
147 Self::Square(s) => 4 * s,
148 }
149 }
150
151 /// Scales the shape by an area factor while preserving aspect ratio.
152 ///
153 /// Uses integer square root approximation for scaling.
154 ///
155 /// # Arguments
156 /// * `factor` - The area scaling factor (e.g., 2 doubles the area).
157 ///
158 /// # Returns
159 /// A new shape with scaled dimensions.
160 pub fn scale_by_area(&self, factor: u32) -> Self {
161 // Integer square root approximation.
162 let scale = (factor as f64).sqrt();
163 match self {
164 Self::Circle(r) => Self::Circle(((*r as f64) * scale) as u32),
165 Self::Rectangle(w, h) => Self::Rectangle(((*w as f64) * scale) as u32, ((*h as f64) * scale) as u32),
166 Self::Square(s) => Self::Square(((*s as f64) * scale) as u32),
167 }
168 }
169}