use crate::{Framebuffer, Lights, color, lights_plane::LIGHT_LOCATIONS};
pub struct CircleBuilder {
color: color::RGB,
center: (f32, f32),
radius: f32,
mask: Lights,
fall_off: Option<f32>,
}
impl CircleBuilder {
pub fn new(color: color::RGB, center: (f32, f32), radius: f32) -> Self {
Self {
color,
center,
radius,
mask: Lights::all(),
fall_off: None,
}
}
#[must_use]
pub fn mask(mut self, mask: Lights) -> Self {
self.mask = mask;
self
}
#[must_use]
pub fn relative_fall_off(mut self, distance: f32) -> Self {
self.fall_off = Some(distance);
self
}
pub fn draw(self, fb: &mut Framebuffer) {
let dist_within_squared = self.radius * self.radius;
for idx in self.mask.indices() {
let (x2, y2) = LIGHT_LOCATIONS[idx];
let dx = self.center.0 - x2;
let dy = self.center.1 - y2;
let dist_squared = dx * dx + dy * dy;
if dist_squared < dist_within_squared {
let c = if let Some(fall_off_distance) = self.fall_off {
let relative_dist = dist_squared.sqrt() / self.radius;
let percent = if relative_dist < fall_off_distance {
1.0
} else {
1. - ((relative_dist - fall_off_distance) / (1.0 - fall_off_distance))
};
color::dim_to(self.color, percent)
} else {
self.color
};
fb.set_color(Lights::from_index(idx), c);
}
}
}
}