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
|
use crate::element::Polygon;
use crate::style::ShapeStyle;
/// The surface series.
///
/// Currently the surface is representing any surface in form
/// y = f(x,z)
///
/// TODO: make this more general
pub struct SurfaceSeries<X, Y, Z> {
x_data: Vec<X>,
y_data: Vec<Y>,
z_data: Vec<Z>,
style: ShapeStyle,
size: usize,
state: usize,
}
impl<X, Y, Z> SurfaceSeries<X, Y, Z> {
pub fn new<XS, ZS, YF, S>(xs: XS, zs: ZS, y_func: YF, style: S) -> Self
where
YF: Fn(&X, &Z) -> Y,
XS: Iterator<Item = X>,
ZS: Iterator<Item = Z>,
S: Into<ShapeStyle>,
{
let x_data: Vec<_> = xs.collect();
let z_data: Vec<_> = zs.collect();
let y_data: Vec<_> = x_data
.iter()
.map(|x| z_data.iter().map(move |z| (x, z)))
.flatten()
.map(|(x, z)| y_func(x, z))
.collect();
let size = (x_data.len().max(1) - 1) * (z_data.len().max(1) - 1);
Self {
x_data,
y_data,
z_data,
style: style.into(),
size,
state: 0,
}
}
fn point_at(&self, x: usize, z: usize) -> (X, Y, Z)
where
X: Clone,
Y: Clone,
Z: Clone,
{
(
self.x_data[x].clone(),
self.y_data[x * self.z_data.len() + z].clone(),
self.z_data[z].clone(),
)
}
}
impl<X: Clone, Y: Clone, Z: Clone> Iterator for SurfaceSeries<X, Y, Z> {
type Item = Polygon<(X, Y, Z)>;
fn next(&mut self) -> Option<Self::Item> {
if self.size <= self.state {
return None;
}
let x = self.state / (self.z_data.len() - 1);
let z = self.state % (self.z_data.len() - 1);
self.state += 1;
Some(Polygon::new(
vec![
self.point_at(x, z),
self.point_at(x, z + 1),
self.point_at(x + 1, z + 1),
self.point_at(x + 1, z),
],
self.style.clone(),
))
}
}
|