UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
blend.hpp
1
45#ifndef UFO_VISION_COLOR_BLEND_HPP
46#define UFO_VISION_COLOR_BLEND_HPP
47
48// UFO
49#include <ufo/vision/color/arithmetic.hpp>
50#include <ufo/vision/color/concepts.hpp>
51#include <ufo/vision/color/convert.hpp>
52#include <ufo/vision/color/type_traits.hpp>
53
54// STL
55#include <algorithm>
56#include <concepts>
57#include <iterator>
58#include <ranges>
59
60namespace ufo
61{
77template <Color C>
78[[nodiscard]] constexpr C blend(C a, C const& b, float t)
79{
80 using D = typename color_traits<C>::template rebind_value<float>;
81
82 if constexpr (std::same_as<C, D>) {
83 return a + t * (b - a);
84 } else {
85 return convert<C>(blend(convert<D>(a), convert<D>(b), t));
86 }
87}
88
99template <std::ranges::input_range R, std::ranges::input_range W>
100 requires Color<std::ranges::range_value_t<R>> &&
101 std::floating_point<std::ranges::range_value_t<W>>
102[[nodiscard]] constexpr std::ranges::range_value_t<R> blend(R&& r, W&& w)
103{
104 using C = std::ranges::range_value_t<R>;
105 using D = typename color_traits<C>::template rebind_value<float>;
106
107 if constexpr (std::same_as<C, D>) {
108 return std::ranges::fold_left(
109 std::views::zip(r, w) | std::views::transform([](auto&& z) {
110 auto [c, weight] = z;
111 return c * weight;
112 }),
113 D{}, std::plus{});
114 } else {
115 return convert<C>(std::ranges::fold_left(
116 std::views::zip(r, w) | std::views::transform([](auto&& z) {
117 auto [c, weight] = z;
118 return convert<D>(c) * weight;
119 }),
120 D{}, std::plus{}));
121 }
122}
123
134template <std::input_iterator InputIt1, std::sentinel_for<InputIt1> Sentinel,
135 std::input_iterator InputIt2>
136 requires Color<std::iter_value_t<InputIt1>> &&
137 std::floating_point<std::iter_value_t<InputIt2>>
138[[nodiscard]] constexpr std::iter_value_t<InputIt1> blend(InputIt1 first, Sentinel last,
139 InputIt2 first_weight)
140{
141 auto r = std::ranges::subrange(std::move(first), std::move(last));
142 auto w = std::views::repeat(0.0f) |
143 std::views::transform([first_weight, i = 0](auto) mutable {
144 return *std::next(first_weight, i++);
145 });
146 return blend(r, w);
147}
148
157template <std::ranges::input_range R, std::floating_point T>
158 requires Color<std::ranges::range_value_t<R>>
159[[nodiscard]] constexpr std::ranges::range_value_t<R> blend(R&& r,
160 std::initializer_list<T> w)
161{
162 return blend(std::forward<R>(r), std::ranges::subrange(w));
163}
164
173template <Color C, std::floating_point T>
174[[nodiscard]] constexpr C blend(std::initializer_list<C> r, std::initializer_list<T> w)
175{
176 return blend(std::ranges::subrange(r), std::ranges::subrange(w));
177}
178
182} // namespace ufo
183
184#endif // UFO_VISION_COLOR_BLEND_HPP
constexpr C blend(C a, C const &b, float t)
Blends two colors using a factor t.
Definition blend.hpp:78
constexpr weight_type_t< C > weight(C color) noexcept
Returns the weight of color, or 1 if color has no weight field.
Definition weight.hpp:67
All vision-related classes and functions.
Definition cloud.hpp:49
constexpr T b(Lab< T, Flags > color) noexcept
Returns the un-weighted blue–yellow axis value.
Definition lab.hpp:326
constexpr T a(Lab< T, Flags > color) noexcept
Returns the un-weighted green–red axis value.
Definition lab.hpp:310
Primary template - intentionally undefined.