-
Notifications
You must be signed in to change notification settings - Fork 4
/
polar.rs
125 lines (116 loc) · 4.21 KB
/
polar.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use glifparser::glif::mfek::point::MFEKPointCommon;
/// This module adds math functions to types in glifparser.
use glifparser::{Handle, Point, PointData, PointType, WhichHandle};
use std::f32::consts;
use crate::bezier::Bezier;
use crate::vector::Vector;
pub trait PolarCoordinates {
/// Considering the point location as the origin, returns handle's position in Cartesian
/// coordinates (irrespective of glyph origin)
fn cartesian(&self, wh: WhichHandle) -> (f32, f32);
/// Returns theta (ϑ) in radians (_Cf._ [`f32::to_radians`])
fn polar(&self, wh: WhichHandle) -> (f32, f32);
/// Expects theta (ϑ) in degrees (_Cf._ [`f32::to_degrees`])
fn set_polar(&mut self, wh: WhichHandle, polar: (f32, f32));
}
impl Bezier {
fn point_from_bezier_handle(&self, wh: WhichHandle) -> Point<()> {
let (p, h) = match wh {
WhichHandle::A => (self.w1, self.w2),
WhichHandle::B => (self.w4, self.w3),
WhichHandle::Neither => unreachable!(),
};
let mut gp: Point<()> =
Vector::to_point(p, Handle::Colocated, Handle::Colocated, PointType::Line);
let gh: Handle = Vector::to_handle(h);
match wh {
WhichHandle::A => {
gp.a = gh;
}
WhichHandle::B => {
gp.b = gh;
}
WhichHandle::Neither => unreachable!(),
}
gp
}
}
impl PolarCoordinates for Bezier {
fn cartesian(&self, wh: WhichHandle) -> (f32, f32) {
let p = Bezier::point_from_bezier_handle(self, wh);
p.cartesian(wh)
}
fn polar(&self, wh: WhichHandle) -> (f32, f32) {
let p = Bezier::point_from_bezier_handle(self, wh);
p.polar(wh)
}
fn set_polar(&mut self, wh: WhichHandle, polar: (f32, f32)) {
let mut p = Bezier::point_from_bezier_handle(self, wh);
p.set_polar(WhichHandle::Neither, polar);
let h = &mut match wh {
WhichHandle::A => self.w2,
WhichHandle::B => self.w3,
WhichHandle::Neither => unreachable!(),
};
h.x = p.x as f64;
h.y = p.y as f64;
}
}
use WhichHandle::{Neither, A, B};
impl<PD: PointData> PolarCoordinates for Point<PD> {
fn cartesian(&self, wh: WhichHandle) -> (f32, f32) {
let (x, y) = match wh {
Neither => (self.x, self.y),
A => self.handle_or_colocated(WhichHandle::A, &|f| f, &|f| f),
B => self.handle_or_colocated(WhichHandle::B, &|f| f, &|f| f),
};
(self.x - x, self.y - y)
}
fn polar(&self, wh: WhichHandle) -> (f32, f32) {
let (x, y) = self.cartesian(wh);
let r = (x.powf(2.) + y.powf(2.)).sqrt();
let theta = y.atan2(x);
(r, theta)
}
fn set_polar(&mut self, wh: WhichHandle, (r, theta): (f32, f32)) {
let x = self.x + (r * (theta * (consts::PI / 180.)).cos());
let y = self.y + (r * (theta * (consts::PI / 180.)).sin());
match wh {
Neither => {
self.x = x;
self.y = y;
}
A => {
self.a = Handle::At(x, y);
}
B => {
self.b = Handle::At(x, y);
}
};
}
}
impl<PD: PointData> PolarCoordinates for &mut dyn MFEKPointCommon<PD> {
fn cartesian(&self, wh: WhichHandle) -> (f32, f32) {
let (x, y) = match wh {
Neither => (self.x(), self.y()),
A => self.get_handle_position(WhichHandle::A).unwrap(),
B => self.get_handle_position(WhichHandle::B).unwrap(),
};
(self.x() - x, self.y() - y)
}
fn polar(&self, wh: WhichHandle) -> (f32, f32) {
let (x, y) = self.cartesian(wh);
let r = (x.powf(2.) + y.powf(2.)).sqrt();
let theta = y.atan2(x);
(r, theta)
}
fn set_polar(&mut self, wh: WhichHandle, (r, theta): (f32, f32)) {
let x = self.x() + (r * (theta * (consts::PI / 180.)).cos());
let y = self.y() + (r * (theta * (consts::PI / 180.)).sin());
match wh {
Neither => self.set_position(x, y),
A => self.set_handle(WhichHandle::A, Handle::At(x, y)),
B => self.set_handle(WhichHandle::B, Handle::At(x, y)),
};
}
}