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
|
use crate::{color::Color, Sample};
pub struct Matrix {
pub inner: Box<dyn Sample>,
pub matrix: ((f64, f64), (f64, f64)),
}
impl Sample for Matrix {
fn sample(&mut self, x: f64, y: f64) -> Color {
let (x, y) = (
x * self.matrix.0 .0 + y * self.matrix.0 .1,
x * self.matrix.1 .0 + y * self.matrix.1 .1,
);
self.inner.sample(x, y)
}
}
pub struct Polar(pub Box<dyn Sample>);
impl Sample for Polar {
fn sample(&mut self, x: f64, y: f64) -> Color {
let ang = x.atan2(y);
let dist = (x * x + y * y).sqrt();
self.0.sample(ang, dist)
}
}
pub struct Transpose(pub Box<dyn Sample>);
impl Sample for Transpose {
fn sample(&mut self, x: f64, y: f64) -> Color {
self.0.sample(y, x)
}
}
pub struct Translate {
pub inner: Box<dyn Sample>,
pub offset: (f64, f64),
}
impl Sample for Translate {
fn sample(&mut self, x: f64, y: f64) -> Color {
self.inner.sample(x - self.offset.0, y - self.offset.1)
}
}
pub enum CompositeOperation {
Add,
Subtract,
Multiply,
Mix(f64),
}
pub struct Composite {
pub a: Box<dyn Sample>,
pub b: Box<dyn Sample>,
pub mode: CompositeOperation,
}
impl Sample for Composite {
fn sample(&mut self, x: f64, y: f64) -> Color {
let a = self.a.sample(x, y);
let b = self.b.sample(x, y);
match self.mode {
CompositeOperation::Add => Color {
r: a.r + b.r,
g: a.g + b.g,
b: a.b + b.b,
},
CompositeOperation::Subtract => Color {
r: a.r - b.r,
g: a.g - b.g,
b: a.b - b.b,
},
CompositeOperation::Multiply => Color {
r: a.r * b.r,
g: a.g * b.g,
b: a.b * b.b,
},
CompositeOperation::Mix(f) => Color {
r: a.r * (1.0 - f) + b.r * f,
g: a.g * (1.0 - f) + b.g * f,
b: a.b * (1.0 - f) + b.b * f,
},
}
}
}
|