Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
158: Make `Take` iterator for gradient inclusive of both end colors, add tests r=Ogeon a=okaneco As mentioned in the third point of #156, this PR includes the bounds of the gradient along with more equal distribution of colors returned from the iterator. In the current version of the iterator, `(self.from_head) / (self.len)` will approach 1 but never equal 1 which results in the upper gradient bound being excluded. The current behavior of `take()` is surprising if one expects the last color step to be the max color of the gradient. This PR increases step distance so the user receives an iterator of colors that evenly traverses from the minimum bound of the gradient to the maximum. The step is increased by subtracting 1 from `self.len` in the calculation of `i`. The calculation for `i` will then include - `0` when `self.from_head` is `0` - `1` when `self.from_head == self.len - 1`. The assignment of `i` has a conditional for when `self.len` is `1`. This avoids division by 0 which results in NaN parameters for the iterator color returned in the case of `take(1)`. The check needed to be added to the `DoubleEndedIterator`, otherwise it would NaN on `1` as well. The behavior of `take(1)` before this PR is to supply the minimum color in the gradient. Pictured below is an example of the difference between current behavior and this PR in 3 sets of Lch gradients. The 1st, 3rd, and 5th rows are the current implementation of the iterator and the others are from the PR with the final step being inclusive of the maximum gradient color specified. The gradients are no longer skewed towards the beginning. The penultimate steps are very close to the current behavior's final step. ![image of 6 stepped gradients](https://raw.githubusercontent.com/okaneco/images/master/inclusive_grad.png) --- `gradient::test::simple_slice` fails as a result of this PR. ``` ---- gradient::test::simple_slice stdout ---- thread 'gradient::test::simple_slice' panicked at 'assert_relative_eq!(t1, t2) left = Rgb { red: 0.8888888888888888, green: 0.0, blue: 0.1111111111111111, standard: PhantomData } right = Rgb { red: 0.875, green: 0.0, blue: 0.125, standard: PhantomData } ', palette/src/gradient.rs:453:13 ``` ```rust #[test] fn simple_slice() { let g1 = Gradient::new(vec![ LinSrgb::new(1.0, 0.0, 0.0), LinSrgb::new(0.0, 0.0, 1.0), ]); let g2 = g1.slice(..0.5); let v1: Vec<_> = g1.take(10).take(5).collect(); let v2: Vec<_> = g2.take(5).collect(); for (t1, t2) in v1.iter().zip(v2.iter()) { assert_relative_eq!(t1, t2); } } ``` Co-authored-by: okaneco <[email protected]>
- Loading branch information