refactor(specctra-core/math/Circle): factor out (angle -> position) routine

This commit is contained in:
Alain Emilia Anna Zscheile 2024-12-11 00:13:52 +01:00
parent dfff4ff4c2
commit fc9c8c3396
4 changed files with 43 additions and 13 deletions

View File

@ -14,6 +14,19 @@ pub struct PointWithRotation {
pub rot: f64,
}
impl Circle {
/// Calculate the point that lies on the circle at angle `phi`,
/// relative to coordinate axes.
///
/// `phi` is the angle given in radians starting at `(r, 0)`.
pub fn position_at_angle(&self, phi: f64) -> Point {
geo::point! {
x: self.pos.0.x + self.r * phi.cos(),
y: self.pos.0.y + self.r * phi.sin()
}
}
}
impl Sub for Circle {
type Output = Self;

View File

@ -392,6 +392,23 @@ pub struct Point {
pub y: f64,
}
impl From<geo::Point> for Point {
#[inline(always)]
fn from(z: geo::Point) -> Self {
Point { x: z.0.x, y: z.0.y }
}
}
impl From<Point> for geo::Point {
#[inline(always)]
fn from(z: Point) -> Self {
geo::point! {
x: z.x,
y: z.y
}
}
}
// Custom impl for the case described above
impl<R: std::io::BufRead> ReadDsn<R> for Vec<Point> {
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {

View File

@ -42,13 +42,14 @@ impl<'a> Painter<'a> {
let angle_from = bend.start_angle();
let angle_step = bend.spanned_angle() / 100.0;
let mut points: Vec<egui::Pos2> = vec![];
for i in 0..=100 {
let x = circle.pos.x() + circle.r * (angle_from + i as f64 * angle_step).cos();
let y = circle.pos.y() + circle.r * (angle_from + i as f64 * angle_step).sin();
points.push(self.transform.mul_pos([x as f32, -y as f32].into()));
}
let points = (0..=100)
.into_iter()
.map(|i| circle.position_at_angle(angle_from + i as f64 * angle_step))
.map(|point| {
self.transform
.mul_pos([point.0.x as f32, -point.0.y as f32].into())
})
.collect();
egui::Shape::line(
points,

View File

@ -101,13 +101,12 @@ impl SpecctraDesign {
(0..=segment_count)
.into_iter()
.map(|i| angle_from + i as f64 * angle_step)
.map(|phi| {
let x = circle.pos.x() + circle.r * phi.cos();
let y = circle.pos.y() + circle.r * phi.sin();
structure::Point { x, y }
.map(|i| {
circle
.position_at_angle(angle_from + i as f64 * angle_step)
.into()
})
.collect()
.collect::<Vec<structure::Point>>()
}
// Intentionally skipped for now.