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
use crate::buffer::Buffer;
use crate::pixel::Pixel;
pub trait Interpolation<P: Pixel, B: Buffer<P>> {
fn interpolate(&self, buffer: &B, x: f64, y: f64) -> P;
}
#[derive(Clone)]
pub struct NearestNeighbor;
impl<P: Pixel, B: Buffer<P>> Interpolation<P, B> for NearestNeighbor {
fn interpolate(&self, buffer: &B, x: f64, y: f64) -> P {
let (width, height) = buffer.dimensions();
buffer
.get_pixel(
(x.rem_euclid(width as f64).floor() as u32).min(width - 1),
(y.rem_euclid(height as f64).floor() as u32).min(height - 1),
)
.clone()
}
}
#[derive(Clone)]
pub struct Bilinear;
impl<P: Pixel, B: Buffer<P>> Interpolation<P, B> for Bilinear {
fn interpolate(&self, buffer: &B, x: f64, y: f64) -> P {
let (width, height) = buffer.dimensions();
let mut x = x.rem_euclid(width as f64);
let mut y = y.rem_euclid(height as f64);
let x2 = (x as u32 + 1) % width;
let y2 = (y as u32 + 1) % height;
if x as u32 == width {
x = width as f64 - 0.01;
}
if y as u32 == height {
y = height as f64 - 0.01;
}
buffer
.get_pixel(x as u32, y as u32)
.lerp(buffer.get_pixel(x2, y as u32), x.fract())
.lerp(
&buffer
.get_pixel(x as u32, y2)
.lerp(buffer.get_pixel(x2, y2), x.fract()),
y.fract(),
)
}
}