From 423c928c9c06a44063a89474633b8ccd8176aded Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Mon, 11 Dec 2023 21:33:41 -0700
Subject: [PATCH 1/6] set_at_dir_from, set_at_angle_from

closes #15
---
 sled/src/sled/mod.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index 1a6ed68..95566b9 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -405,10 +405,32 @@ impl Sled {
         }
     }
 
+    pub fn set_at_dir_from(&mut self, pos: Vec2, dir: Vec2, color: Rgb) -> Result<(), SledError> {
+        match self.raycast_for_index(pos, dir) {
+            None => Err(SledError {
+                message: format!("No LED in directon: {}", dir),
+            }),
+            Some(index) => {
+                self.leds[index].color = color;
+                Ok(())
+            }
+        }
+    }
+
     pub fn set_at_angle(&mut self, angle: f32, color: Rgb) -> Result<(), SledError> {
         let dir = Vec2::from_angle(angle);
         self.set_at_dir(dir, color)
     }
+
+    pub fn set_at_angle_from(
+        &mut self,
+        pos: Vec2,
+        angle: f32,
+        color: Rgb,
+    ) -> Result<(), SledError> {
+        let dir = Vec2::from_angle(angle);
+        self.set_at_dir_from(dir, pos, color)
+    }
 }
 
 /// position-based read and write methods

From 1db26eb55ad376510f505fd6d4744fb3e3567ed4 Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Mon, 11 Dec 2023 21:59:43 -0700
Subject: [PATCH 2/6] index and index range [] operators

closes #12
---
 sled/src/sled/mod.rs | 53 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index 95566b9..e6addd9 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -8,6 +8,7 @@ use config::{Config, LineSegment};
 use led::Led;
 
 use glam::Vec2;
+use std::ops::{Index, IndexMut};
 use std::{ops::Range, usize};
 
 #[allow(dead_code)]
@@ -179,15 +180,55 @@ impl Sled {
     }
 }
 
-/// Index range-based read and write methods
-impl Sled {
-    pub fn get_range(&self, index_range: Range<usize>) -> &[Led] {
+impl Index<usize> for Sled {
+    type Output = Led;
+
+    fn index(&self, index: usize) -> &Self::Output {
+        &self.leds[index]
+    }
+}
+
+impl IndexMut<usize> for Sled {
+    fn index_mut(&mut self, index: usize) -> &mut Led {
+        &mut self.leds[index]
+    }
+}
+
+impl Index<Range<usize>> for Sled {
+    type Output = [Led];
+
+    fn index(&self, index_range: Range<usize>) -> &[Led] {
         &self.leds[index_range]
     }
+}
 
-    pub fn get_range_mut(&mut self, index_range: Range<usize>) -> &mut [Led] {
+impl IndexMut<Range<usize>> for Sled {
+    fn index_mut(&mut self, index_range: Range<usize>) -> &mut [Led] {
         &mut self.leds[index_range]
     }
+}
+
+/// Index range-based read and write methods
+impl Sled {
+    pub fn get_range(&self, index_range: Range<usize>) -> Result<&[Led], SledError> {
+        if index_range.end < self.num_leds {
+            Ok(&self.leds[index_range])
+        } else {
+            Err(SledError {
+                message: format!("Index range extends beyond size of system."),
+            })
+        }
+    }
+
+    pub fn get_range_mut(&mut self, index_range: Range<usize>) -> Result<&mut [Led], SledError> {
+        if index_range.end < self.num_leds {
+            Ok(&mut self.leds[index_range])
+        } else {
+            Err(SledError {
+                message: format!("Index range extends beyond size of system."),
+            })
+        }
+    }
 
     pub fn set_range(&mut self, index_range: Range<usize>, color: Rgb) -> Result<(), SledError> {
         if index_range.end > self.num_leds {
@@ -215,7 +256,7 @@ impl Sled {
 impl Sled {
     pub fn get_segment(&self, segment_index: usize) -> Option<&[Led]> {
         let (start, end) = *self.line_segment_endpoint_indices.get(segment_index)?;
-        Some(self.get_range(start..end))
+        Some(&self[start..end])
     }
 
     pub fn get_segment_mut(&mut self, segment_index: usize) -> Option<&mut [Led]> {
@@ -224,7 +265,7 @@ impl Sled {
         }
 
         let (start, end) = self.line_segment_endpoint_indices[segment_index];
-        Some(self.get_range_mut(start..end))
+        Some(&mut self[start..end])
     }
 
     pub fn set_segment(&mut self, segment_index: usize, color: Rgb) -> Result<(), SledError> {

From 1913121d9b00341aa81497aaceb1b12675bdfcff Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Mon, 11 Dec 2023 23:23:57 -0700
Subject: [PATCH 3/6] improved distance-based methods, particularly those
 relative to center point.

closes #11
---
 sled/src/sled/mod.rs | 227 ++++++++++++++++++++++++-------------------
 1 file changed, 128 insertions(+), 99 deletions(-)

diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index e6addd9..8d5069f 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -20,6 +20,7 @@ pub struct Sled {
     // utility lookup tables
     line_segment_endpoint_indices: Vec<(usize, usize)>,
     vertex_indices: Vec<usize>,
+    index_of_closest: usize,
 }
 
 /// Construction, output, and basic sled info.
@@ -35,11 +36,18 @@ impl Sled {
         let line_segment_endpoint_indices = Sled::line_segment_endpoint_indices(&leds_per_segment);
         let vertex_indices = Sled::vertex_indices(&config);
         let num_leds = leds.len();
+        let index_of_closest = leds
+            .iter()
+            .min_by(|l, r| l.distance().partial_cmp(&r.distance()).unwrap())
+            .unwrap()
+            .index();
+
         Ok(Sled {
             center_point: config.center_point,
             leds,
             num_leds,
             line_segments: config.line_segments,
+            index_of_closest,
             // utility lookup tables
             line_segment_endpoint_indices,
             vertex_indices,
@@ -494,14 +502,22 @@ impl Sled {
         self.alpha_to_index(alpha, segment_index)
     }
 
+    pub fn get_closest(&self) -> &Led {
+        &self.leds[self.index_of_closest]
+    }
+
+    pub fn get_closest_mut(&mut self) -> &mut Led {
+        &mut self.leds[self.index_of_closest]
+    }
+
     pub fn get_closest_to(&self, pos: Vec2) -> &Led {
         let index_of_closest = self.get_index_of_closest_to(pos);
-        self.get(index_of_closest).unwrap()
+        &self[index_of_closest]
     }
 
     pub fn get_closest_to_mut(&mut self, pos: Vec2) -> &mut Led {
         let index_of_closest = self.get_index_of_closest_to(pos);
-        self.get_mut(index_of_closest).unwrap()
+        &mut self[index_of_closest]
     }
 
     pub fn set_closest_to(&mut self, pos: Vec2, color: Rgb) {
@@ -514,8 +530,19 @@ impl Sled {
         for (segment_index, segment) in self.line_segments.iter().enumerate() {
             for alpha in segment.intersects_circle(pos, dist) {
                 let index = self.alpha_to_index(alpha, segment_index);
-                let led = self.get(index).unwrap();
-                all_at_distance.push(led);
+                all_at_distance.push(&self[index]);
+            }
+        }
+
+        all_at_distance
+    }
+
+    fn indices_at_dist(&self, pos: Vec2, dist: f32) -> Vec<usize> {
+        let mut all_at_distance: Vec<usize> = vec![];
+        for (segment_index, segment) in self.line_segments.iter().enumerate() {
+            for alpha in segment.intersects_circle(pos, dist) {
+                let index = self.alpha_to_index(alpha, segment_index);
+                all_at_distance.push(index);
             }
         }
 
@@ -523,56 +550,42 @@ impl Sled {
     }
 
     pub fn get_at_dist_from_mut(&mut self, pos: Vec2, dist: f32) -> Vec<&mut Led> {
-        // not happy with this solution, but best I could think of.
-        // Do things the "easy" way by using get_at_dist, and then
-        // filter out a new list of mutable references by index to narrow
-        // down to just those
+        // Best solution I could think of. Use our old circle intersection
+        // test and use that to get a list of indices for leds that are at that
+        // distance. filter down our led list to just those with matching indices.
 
-        let mut indices: Vec<usize> = self
-            .get_at_dist_from(pos, dist)
-            .iter()
-            .map(|led| led.index())
-            .collect();
+        let mut matches = self.indices_at_dist(pos, dist);
 
         let filtered: Vec<&mut Led> = self
             .leds
             .iter_mut()
             .filter(|led| {
-                let search = indices.iter().position(|i| *i == led.index());
-                match search {
-                    Some(i) => {
-                        indices.remove(i);
-                        return true;
-                    }
-                    None => return false,
+                if matches.is_empty() {
+                    return false;
+                }
+                let search = matches.iter().position(|x| *x == led.index());
+                if let Some(index) = search {
+                    matches.swap_remove(index);
+                    true
+                } else {
+                    false
                 }
             })
             .collect();
-
         filtered
     }
 
     pub fn set_at_dist_from(&mut self, pos: Vec2, dist: f32, color: Rgb) -> Result<(), SledError> {
-        let indices: Vec<usize> = self
-            .get_at_dist_from(pos, dist)
-            .iter()
-            .map(|led| led.index())
-            .collect();
+        let mut leds_at_dist = self.get_at_dist_from_mut(pos, dist);
 
-        if indices.is_empty() {
-            return Err(SledError {
-                message: format!(
-                    "No LEDs exist at a distance of {} from the center point.",
-                    dist
-                ),
-            });
-        }
-
-        for index in indices {
-            self.leds[index].color = color;
+        if leds_at_dist.is_empty() {
+            Err(SledError {
+                message: format!("No LEDs exist within a distance of {} from {}", dist, pos),
+            })
+        } else {
+            leds_at_dist.set_all(color);
+            Ok(())
         }
-
-        Ok(())
     }
 
     pub fn get_at_dist(&self, dist: f32) -> Vec<&Led> {
@@ -599,9 +612,7 @@ impl Sled {
                 let first = self.alpha_to_index(*first.unwrap(), segment_index);
                 let second = self.alpha_to_index(*second.unwrap(), segment_index);
                 let range = first.min(second)..first.max(second);
-                for i in range {
-                    all_within_distance.push(self.get(i).unwrap());
-                }
+                all_within_distance.extend(&self[range]);
             }
         }
 
@@ -609,26 +620,11 @@ impl Sled {
     }
 
     pub fn get_within_dist_from_mut(&mut self, pos: Vec2, dist: f32) -> Vec<&mut Led> {
-        // This is even worse than get_at_dist_from_mut as there are going to be way more matching indices
-        let mut indices: Vec<usize> = self
-            .get_within_dist_from(pos, dist)
-            .iter()
-            .map(|led| led.index())
-            .collect();
-
+        let dist_sq = dist.powi(2);
         let filtered: Vec<&mut Led> = self
             .leds
             .iter_mut()
-            .filter(|led| {
-                let search = indices.iter().position(|i| *i == led.index());
-                match search {
-                    Some(i) => {
-                        indices.remove(i);
-                        return true;
-                    }
-                    None => return false,
-                }
-            })
+            .filter(|led| led.position().distance_squared(pos) < dist_sq)
             .collect();
 
         filtered
@@ -640,39 +636,14 @@ impl Sled {
         dist: f32,
         color: Rgb,
     ) -> Result<(), SledError> {
-        // let mut ranges = vec![];
-        // for (segment_index, segment) in self.line_segments.iter().enumerate() {
-        //     let intersections = segment.intersects_solid_circle(pos, dist);
-        //     let first = intersections.get(0);
-        //     let second = intersections.get(1);
-
-        //     if first.is_some() && second.is_some() {
-        //         let first = self.alpha_to_index(*first.unwrap(), segment_index);
-        //         let second = self.alpha_to_index(*second.unwrap(), segment_index);
-        //         let range = first.min(second)..first.max(second);
-        //         ranges.push(range);
-        //     }
-        // }
-
-        // if ranges.is_empty() {
-        //     return Err(SledError {
-        //         message: format!(
-        //             "No LEDs exist within a distance of {} from the center point.",
-        //             dist
-        //         ),
-        //     });
-        // }
-
-        // for range in ranges {
-        //     self.set_range(range, color).unwrap();
-        // }
         let target_sq = dist.powi(2);
+
         for led in &mut self.leds {
             if led.position().distance_squared(pos) < target_sq {
                 led.color = color;
             }
         }
-
+        
         Ok(())
     }
 
@@ -681,16 +652,28 @@ impl Sled {
     }
 
     pub fn get_within_dist_mut(&mut self, dist: f32) -> Vec<&mut Led> {
-        self.get_within_dist_from_mut(self.center_point, dist)
+        let filtered: Vec<&mut Led> = self
+            .leds
+            .iter_mut()
+            .filter(|led| led.distance() < dist)
+            .collect();
+        filtered
     }
 
     pub fn set_within_dist(&mut self, dist: f32, color: Rgb) -> Result<(), SledError> {
-        for led in &mut self.leds {
-            if led.distance() < dist {
-                led.color = color;
-            }
+        let mut within_dist = self.get_within_dist_mut(dist);
+
+        if within_dist.is_empty() {
+            Err(SledError {
+                message: format!(
+                    "No LEDs exist within a distance of {} from the center",
+                    dist
+                ),
+            })
+        } else {
+            within_dist.set_all(color);
+            Ok(())
         }
-        Ok(())
     }
 }
 
@@ -824,6 +807,7 @@ pub trait CollectionOfLeds {
     // Indices, ranges, and some others might not make sense.
 
     fn filter(&self, filter: impl Fn(&Led) -> bool) -> Vec<&Led>;
+    fn get_closest_to(&self, center_point: Vec2) -> &Led;
 }
 
 pub trait CollectionOfLedsMut {
@@ -834,9 +818,13 @@ pub trait CollectionOfLedsMut {
     // - mapping methods
     // - etc
 
+    fn filter(&self, filter: impl Fn(&Led) -> bool) -> Vec<&Led>;
+
     fn set_all(&mut self, color: Rgb);
 
-    fn filter(&self, filter: impl Fn(&Led) -> bool) -> Vec<&Led>;
+    fn get_closest_to(&self, pos: Vec2) -> &Led;
+    fn get_closest_to_mut(&mut self, pos: Vec2) -> &mut Led;
+    fn set_closest_to(&mut self, pos: Vec2, color: Rgb);
 
     fn map(&mut self, led_to_color_map: impl Fn(&Led) -> Rgb);
 }
@@ -847,21 +835,62 @@ impl CollectionOfLeds for Vec<&Led> {
         copy.retain(|led| filter(led));
         copy
     }
-}
 
-impl CollectionOfLedsMut for Vec<&mut Led> {
-    fn set_all(&mut self, color: Rgb) {
-        for led in self {
-            led.color = color;
-        }
+    fn get_closest_to(&self, pos: Vec2) -> &Led {
+        self.iter()
+            .min_by(|l, r| {
+                let d1 = l.position().distance_squared(pos);
+                let d2 = r.position().distance_squared(pos);
+                d1.partial_cmp(&d2).unwrap()
+            })
+            .unwrap()
     }
+}
 
+impl CollectionOfLedsMut for Vec<&mut Led> {
     fn filter(&self, filter: impl Fn(&Led) -> bool) -> Vec<&Led> {
         let mut copy: Vec<&Led> = self.iter().map(|led| &**led).collect();
         copy.retain(|led| filter(led));
         copy
     }
 
+    fn get_closest_to(&self, pos: Vec2) -> &Led {
+        self.iter()
+            .min_by(|l, r| {
+                let d1 = l.position().distance_squared(pos);
+                let d2 = r.position().distance_squared(pos);
+                d1.partial_cmp(&d2).unwrap()
+            })
+            .unwrap()
+    }
+
+    fn get_closest_to_mut(&mut self, pos: Vec2) -> &mut Led {
+        self.iter_mut()
+            .min_by(|l, r| {
+                let d1 = l.position().distance_squared(pos);
+                let d2 = r.position().distance_squared(pos);
+                d1.partial_cmp(&d2).unwrap()
+            })
+            .unwrap()
+    }
+
+    fn set_closest_to(&mut self, pos: Vec2, color: Rgb) {
+        self.iter_mut()
+            .min_by(|l, r| {
+                let d1 = l.position().distance_squared(pos);
+                let d2 = r.position().distance_squared(pos);
+                d1.partial_cmp(&d2).unwrap()
+            })
+            .unwrap()
+            .color = color;
+    }
+
+    fn set_all(&mut self, color: Rgb) {
+        for led in self {
+            led.color = color;
+        }
+    }
+
     fn map(&mut self, _led_to_color_map: impl Fn(&Led) -> Rgb) {
         todo!()
     }

From e0e420a746115c8beb12db3227327a623466b172 Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Mon, 11 Dec 2023 23:30:34 -0700
Subject: [PATCH 4/6] set_closest_to(), more consistent choice of indexor

---
 sled/src/sled/mod.rs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index 8d5069f..ef66d29 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -264,7 +264,7 @@ impl Sled {
 impl Sled {
     pub fn get_segment(&self, segment_index: usize) -> Option<&[Led]> {
         let (start, end) = *self.line_segment_endpoint_indices.get(segment_index)?;
-        Some(&self[start..end])
+        Some(&self.leds[start..end])
     }
 
     pub fn get_segment_mut(&mut self, segment_index: usize) -> Option<&mut [Led]> {
@@ -273,7 +273,7 @@ impl Sled {
         }
 
         let (start, end) = self.line_segment_endpoint_indices[segment_index];
-        Some(&mut self[start..end])
+        Some(&mut self.leds[start..end])
     }
 
     pub fn set_segment(&mut self, segment_index: usize, color: Rgb) -> Result<(), SledError> {
@@ -510,14 +510,18 @@ impl Sled {
         &mut self.leds[self.index_of_closest]
     }
 
+    pub fn set_closest(&mut self, color: Rgb) {
+        self.leds[self.index_of_closest].color = color;
+    }
+
     pub fn get_closest_to(&self, pos: Vec2) -> &Led {
         let index_of_closest = self.get_index_of_closest_to(pos);
-        &self[index_of_closest]
+        &self.leds[index_of_closest]
     }
 
     pub fn get_closest_to_mut(&mut self, pos: Vec2) -> &mut Led {
         let index_of_closest = self.get_index_of_closest_to(pos);
-        &mut self[index_of_closest]
+        &mut self.leds[index_of_closest]
     }
 
     pub fn set_closest_to(&mut self, pos: Vec2, color: Rgb) {
@@ -530,7 +534,7 @@ impl Sled {
         for (segment_index, segment) in self.line_segments.iter().enumerate() {
             for alpha in segment.intersects_circle(pos, dist) {
                 let index = self.alpha_to_index(alpha, segment_index);
-                all_at_distance.push(&self[index]);
+                all_at_distance.push(&self.leds[index]);
             }
         }
 
@@ -612,7 +616,7 @@ impl Sled {
                 let first = self.alpha_to_index(*first.unwrap(), segment_index);
                 let second = self.alpha_to_index(*second.unwrap(), segment_index);
                 let range = first.min(second)..first.max(second);
-                all_within_distance.extend(&self[range]);
+                all_within_distance.extend(&self.leds[range]);
             }
         }
 

From 7f1e97eaa18f9ebe15e3a1354dea7b038af7f30c Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Tue, 12 Dec 2023 00:29:09 -0700
Subject: [PATCH 5/6] addressed regression

---
 sled/benches/my_benchmark.rs | 18 ++++++++--------
 sled/src/sled/mod.rs         | 42 ++++++++++++++++++------------------
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/sled/benches/my_benchmark.rs b/sled/benches/my_benchmark.rs
index 05b39ff..43e1726 100644
--- a/sled/benches/my_benchmark.rs
+++ b/sled/benches/my_benchmark.rs
@@ -90,15 +90,15 @@ fn setters(c: &mut Criterion) {
         })
     });
 
-    c.bench_function("set_closest", |b| {
-        b.iter(|| {
-            sled.set_closest(white);
-            sled.set_closest(white);
-            sled.set_closest(white);
-            sled.set_closest(white);
-            sled.set_closest(white);
-        })
-    });
+    // c.bench_function("set_closest", |b| {
+    //     b.iter(|| {
+    //         sled.set_closest(white);
+    //         sled.set_closest(white);
+    //         sled.set_closest(white);
+    //         sled.set_closest(white);
+    //         sled.set_closest(white);
+    //     })
+    // });
 
     c.bench_function("set_at_dist", |b| {
         b.iter(|| {
diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index ef66d29..e5161e9 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -580,16 +580,22 @@ impl Sled {
     }
 
     pub fn set_at_dist_from(&mut self, pos: Vec2, dist: f32, color: Rgb) -> Result<(), SledError> {
-        let mut leds_at_dist = self.get_at_dist_from_mut(pos, dist);
+        let indices: Vec<usize> = self.indices_at_dist(pos, dist);
 
-        if leds_at_dist.is_empty() {
-            Err(SledError {
-                message: format!("No LEDs exist within a distance of {} from {}", dist, pos),
-            })
-        } else {
-            leds_at_dist.set_all(color);
-            Ok(())
+        if indices.is_empty() {
+            return Err(SledError {
+                message: format!(
+                    "No LEDs exist at a distance of {} from the center point.",
+                    dist
+                ),
+            });
+        }
+
+        for index in indices {
+            self.leds[index].color = color;
         }
+
+        Ok(())
     }
 
     pub fn get_at_dist(&self, dist: f32) -> Vec<&Led> {
@@ -647,7 +653,7 @@ impl Sled {
                 led.color = color;
             }
         }
-        
+
         Ok(())
     }
 
@@ -665,19 +671,13 @@ impl Sled {
     }
 
     pub fn set_within_dist(&mut self, dist: f32, color: Rgb) -> Result<(), SledError> {
-        let mut within_dist = self.get_within_dist_mut(dist);
-
-        if within_dist.is_empty() {
-            Err(SledError {
-                message: format!(
-                    "No LEDs exist within a distance of {} from the center",
-                    dist
-                ),
-            })
-        } else {
-            within_dist.set_all(color);
-            Ok(())
+        for led in &mut self.leds {
+            if led.distance() < dist {
+                led.color = color;
+            }
         }
+
+        Ok(())
     }
 }
 

From 3a3c515de39be037a20231bdb0544da2ca419ba4 Mon Sep 17 00:00:00 2001
From: David Cosby <davjcosby@gmail.com>
Date: Tue, 12 Dec 2023 00:49:50 -0700
Subject: [PATCH 6/6] inequality logic fixes

---
 sled/src/sled/mod.rs | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/sled/src/sled/mod.rs b/sled/src/sled/mod.rs
index e5161e9..3624f6d 100644
--- a/sled/src/sled/mod.rs
+++ b/sled/src/sled/mod.rs
@@ -165,7 +165,7 @@ impl Sled {
     }
 
     pub fn set(&mut self, index: usize, color: Rgb) -> Result<(), SledError> {
-        if index > self.num_leds {
+        if index >= self.num_leds {
             return Err(SledError {
                 message: format!("LED at index {} does not exist.", index),
             });
@@ -239,7 +239,7 @@ impl Sled {
     }
 
     pub fn set_range(&mut self, index_range: Range<usize>, color: Rgb) -> Result<(), SledError> {
-        if index_range.end > self.num_leds {
+        if index_range.end >= self.num_leds {
             return Err(SledError {
                 message: format!("Index range extends beyond size of system."),
             });
@@ -381,11 +381,7 @@ impl Sled {
         let leds_in_segment = segment.num_leds() as f32;
 
         let target = startpoint_index + (segment_alpha * leds_in_segment).floor() as usize;
-        if target > self.num_leds {
-            target
-        } else {
-            target
-        }
+        target
     }
 
     fn raycast_for_index(&self, start: Vec2, dir: Vec2) -> Option<usize> {