Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • add-intersections
  • agrabowy
  • ak/develop
  • develop
  • feature-fixed_uint
  • feature-units
  • feature/are-orthogonal-fix
  • feature/colors
  • feature/covariance
  • feature/perspective-vulkan
  • feature/restructure
  • jn/develop
  • js/develop
  • js/dito
  • jschakib
  • kersten
  • kschuster
  • kw/develop
  • master
  • noise-functions
  • polygon-wip
  • zs/fix-comp-zero
  • 0.6.0
23 results

Target

Select target project
  • ptrettner/typed-geometry
  • bconze/typed-geometry
  • gkobsik/typed-geometry
3 results
Select Git revision
  • add-intersections
  • agrabowy
  • develop
  • feature-fixed_uint
  • feature-units
  • feature/are-orthogonal-fix
  • feature/covariance
  • feature/perspective-vulkan
  • feature/restructure
  • gkobsik
  • jschakib
  • kersten
  • kschuster
  • kw/develop
  • master
  • noise-functions
  • polygon-wip
  • 0.6.0
18 results
Show changes
Commits on Source (235)
Showing
with 330 additions and 74 deletions
......@@ -2,6 +2,16 @@
Header-only strongly typed math library for graphics and geometry.
> :warning: this repository is an old version (and the last version without clean-core dependency). typed-geometry is being actively developed at https://github.com/project-arcana/typed-geometry.
:warning: How to update :warning:
```
cd your-project/extern/typed-geometry
git remote set-url origin git@github.com:project-arcana/typed-geometry.git
git pull
```
## Usage / Example
......
......@@ -11,7 +11,7 @@
macro(arcana_source_group)
foreach(loop_var ${ARGN})
if (${CMAKE_GENERATOR} MATCHES "Visual Studio")
if (${CMAKE_GENERATOR} MATCHES "Visual Studio" OR WIN32)
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${${loop_var}})
else()
source_group("${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${${loop_var}})
......
......@@ -101,14 +101,15 @@ constexpr ScalarT comp_get(Obj const& v, unsigned char idx, int size, ScalarT fi
}
template <class Obj, class ScalarT>
constexpr bool is_comp_convertible = decltype(detail::test_comp_convertible<Obj, ScalarT>(nullptr))::value;
constexpr bool is_comp_convertible = !std::is_pointer_v<std::remove_reference_t<Obj>> && decltype(detail::test_comp_convertible<Obj, ScalarT>(nullptr))::value;
template <class Obj, class ScalarT>
constexpr bool is_mat_convertible = decltype(detail::test_mat_convertible<Obj, ScalarT>(nullptr))::value;
constexpr bool is_mat_convertible = !std::is_pointer_v<std::remove_reference_t<Obj>> && decltype(detail::test_mat_convertible<Obj, ScalarT>(nullptr))::value;
template <class Obj>
constexpr bool is_comp_dynamic_size = detail::comp_size<Obj>::value < 0;
template <class Obj, int D, class ScalarT>
constexpr bool is_comp_like = is_comp_convertible<Obj, ScalarT> && (is_comp_dynamic_size<Obj> || detail::comp_size<Obj>::value >= D);
constexpr bool is_comp_like
= !std::is_pointer_v<std::remove_reference_t<Obj>> && is_comp_convertible<Obj, ScalarT> && (is_comp_dynamic_size<Obj> || detail::comp_size<Obj>::value >= D);
}
......@@ -8,14 +8,15 @@
#include <typed-geometry/types/vec.hh>
#include <typed-geometry/types/objects/box.hh>
#include <typed-geometry/types/objects/cone.hh>
#include <typed-geometry/types/objects/ellipse.hh>
#include <typed-geometry/types/objects/frustum.hh>
#include <typed-geometry/types/objects/halfspace.hh>
#include <typed-geometry/types/objects/inf_cone.hh>
#include <typed-geometry/types/objects/line.hh>
#include <typed-geometry/types/objects/plane.hh>
#include <typed-geometry/detail/operators/ops_pos.hh>
#include <typed-geometry/functions/vector/dot.hh>
#include <typed-geometry/functions/vector/length.hh>
// Header for all constructors that depend on functions
......@@ -35,6 +36,21 @@ constexpr box<D, ScalarT, D, TraitsT>::box(aabb<D, ScalarT, TraitsT> const& b)
}
}
template <int D, class ScalarT, class TraitsT>
constexpr ellipse<D, ScalarT, D, TraitsT>::ellipse(sphere<D, ScalarT, D, TraitsT> const& s)
{
center = s.center;
semi_axes = mat_t::diag(s.radius);
}
template <class ScalarT, class TraitsT>
constexpr ellipse<2, ScalarT, 3, TraitsT>::ellipse(sphere<2, ScalarT, 3, TraitsT> const& s)
{
center = s.center;
const auto axis1 = any_normal(s.normal);
const auto axis2 = normalize(cross(s.normal, axis1));
semi_axes = mat_t::from_cols(s.radius * axis1, s.radius * axis2);
}
template <int D, class ScalarT>
constexpr plane<D, ScalarT>::plane(dir_t n, pos_t p) : normal(n), dis(dot(vec<D, ScalarT>(p), n))
{
......@@ -49,12 +65,4 @@ constexpr line<D, ScalarT> line<D, ScalarT>::from_points(pos_t a, pos_t b)
{
return line(a, normalize(b - a));
}
template <int D, class ScalarT, class TraitsT>
constexpr inf_cone<D, ScalarT, TraitsT>::inf_cone(cone<D, ScalarT, TraitsT> const& c)
{
apex = c.base.center + c.height * c.base.normal;
opening_dir = -c.base.normal;
opening_angle = ScalarT(2) * angle_between(normalize(c.base.center + any_normal(c.base.normal) * c.base.radius - apex), opening_dir);
}
}
......@@ -6,11 +6,11 @@ namespace tg
{
namespace literals
{
constexpr angle32 operator""_deg(u64 v) { return angle32::from_degree(f32(v)); }
constexpr angle32 operator""_deg(unsigned long long v) { return angle32::from_degree(f32(v)); }
constexpr angle64 operator""_deg(long double v) { return angle64::from_degree(f64(v)); }
constexpr angle32 operator""_degf(long double v) { return angle32::from_degree(f32(v)); }
constexpr angle32 operator""_rad(u64 v) { return angle32::from_radians(f32(v)); }
constexpr angle32 operator""_rad(unsigned long long v) { return angle32::from_radians(f32(v)); }
constexpr angle64 operator""_rad(long double v) { return angle64::from_radians(f64(v)); }
constexpr angle32 operator""_radf(long double v) { return angle32::from_radians(f32(v)); }
} // namespace literals
......
......@@ -2,6 +2,7 @@
#include <typed-geometry/types/comp.hh>
#include <typed-geometry/types/objects/box.hh>
#include <typed-geometry/types/objects/line.hh>
#include <typed-geometry/types/objects/ray.hh>
#include <typed-geometry/types/objects/segment.hh>
......
......@@ -45,7 +45,7 @@ public:
};
template <class T, class Stream>
auto operator<<(Stream& os, optional<T> const& o) -> decltype(os << o.value(), os << "", os)
auto operator<<(Stream& os, optional<T> const& o) -> decltype(os << o.value(), os << std::declval<char const*>(), os)
{
return o.has_value() ? (os << o.value()) : (os << "[empty]");
}
......
......@@ -42,47 +42,46 @@ TG_IMPL_ADD_TRAIT(type_name_prefix, char const*, f16, "f16");
TG_IMPL_ADD_TRAIT(type_name_prefix, char const*, f32, ""); // vec3, not fvec3
TG_IMPL_ADD_TRAIT(type_name_prefix, char const*, f64, "d");
TG_IMPL_ADD_TRAIT(is_scalar, bool, i8, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, i16, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, i32, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, i64, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, u8, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, u16, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, u32, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, u64, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, signed char, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, signed short int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, signed int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, signed long int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, signed long long int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned char, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned short int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned long int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned long long int, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, f8, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, f16, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, f32, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, f64, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, long, true);
TG_IMPL_ADD_TRAIT(is_scalar, bool, unsigned long, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, i8, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, i16, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, i32, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, i64, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, long, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, i8, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, i16, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, i32, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, i64, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, long, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, u8, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, u16, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, u32, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, u64, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned long, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, u8, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, u16, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, u32, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, u64, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned long, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, signed char, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, signed short int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, signed int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, signed long int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, signed long long int, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, signed char, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, signed short int, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, signed int, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, signed long int, true);
TG_IMPL_ADD_TRAIT(is_signed_integer, bool, signed long long int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned char, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned short int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned long int, true);
TG_IMPL_ADD_TRAIT(is_integer, bool, unsigned long long int, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned char, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned short int, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned int, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned long int, true);
TG_IMPL_ADD_TRAIT(is_unsigned_integer, bool, unsigned long long int, true);
TG_IMPL_ADD_TRAIT(is_floating_point, bool, f8, true);
TG_IMPL_ADD_TRAIT(is_floating_point, bool, f16, true);
......@@ -113,4 +112,20 @@ struct is_scalar_t<angle_t<T>>
// abstract scalars are scalars that don't hold a concrete values (e.g. traced types)
TG_IMPL_DEFINE_TRAIT(is_abstract_scalar, bool, false);
template <class T>
struct make_unsigned_t
{
using type = std::make_unsigned_t<T>;
};
template <class T>
using make_unsigned = typename make_unsigned_t<T>::type;
template <class T>
struct make_signed_t
{
using type = std::make_signed_t<T>;
};
template <class T>
using make_signed = typename make_signed_t<T>::type;
} // namespace tg
#pragma once
#include <typed-geometry/types/comp.hh>
#include <typed-geometry/types/dir.hh>
#include <typed-geometry/types/mat.hh>
#include <typed-geometry/types/pos.hh>
......@@ -300,6 +301,15 @@ const size<4, ScalarT> size<4, ScalarT>::ones = {ScalarT(1), ScalarT(1), ScalarT
template <class ScalarT>
const size<4, ScalarT> size<4, ScalarT>::unit = {ScalarT(1), ScalarT(1), ScalarT(1), ScalarT(1)};
template <class ScalarT>
const comp<1, ScalarT> comp<1, ScalarT>::zero = {ScalarT(0)};
template <class ScalarT>
const comp<2, ScalarT> comp<2, ScalarT>::zero = {ScalarT(0), ScalarT(0)};
template <class ScalarT>
const comp<3, ScalarT> comp<3, ScalarT>::zero = {ScalarT(0), ScalarT(0), ScalarT(0)};
template <class ScalarT>
const comp<4, ScalarT> comp<4, ScalarT>::zero = {ScalarT(0), ScalarT(0), ScalarT(0), ScalarT(0)};
template <int C, int R, class ScalarT>
const mat<C, R, ScalarT> mat<C, R, ScalarT>::zero = {};
template <int C, int R, class ScalarT>
......
#pragma once
#include <cstdint>
#include <type_traits>
namespace tg
{
using u8 = unsigned char;
using u16 = unsigned short;
using u32 = unsigned int;
using u64 = unsigned long long;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using size_t = decltype(sizeof(0));
......@@ -35,10 +36,25 @@ template <>
struct priority_tag<0>
{
};
// see https://stackoverflow.com/questions/44395169/why-is-sfinae-on-if-constexpr-not-allowed
template <template <class...> class, class, class...>
struct can_apply : std::false_type
{
};
template <template <class...> class Z, class... Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...> : std::true_type
{
};
} // namespace detail
template <template <class...> class Z, class... Ts>
constexpr bool can_apply = detail::can_apply<Z, void, Ts...>::value;
template <class...>
constexpr bool always_false = false;
/// same as always_false, but for non-type template parameters, e.g. always_false_v<Dimension>
template <auto...>
constexpr bool always_false_v = false;
template <class...>
using void_t = void;
......@@ -167,7 +183,8 @@ To bit_cast(From f)
static_assert(sizeof(From) == sizeof(To), "can only bitcast between same-size types");
// NOTE: std::memcpy includes an std header which we want to avoid
union {
union
{
From from;
To to;
} u;
......@@ -241,6 +258,27 @@ struct is_range_t<Container,
>> : std::true_type
{
};
template <class Container, class = void>
struct is_any_range_t : false_type
{
};
template <class ElementT, size_t N>
struct is_any_range_t<ElementT[N]> : true_type
{
};
template <class ElementT, size_t N>
struct is_any_range_t<ElementT (&)[N]> : true_type
{
};
template <class Container>
struct is_any_range_t<Container,
std::void_t< //
decltype(std::declval<Container>().begin()), //
decltype(std::declval<Container>().end()) //
>> : std::true_type
{
};
}
template <class Container, class ElementT>
......@@ -249,6 +287,9 @@ static constexpr bool is_container = sizeof(detail::container_test<Container, El
template <class Container, class ElementT>
static constexpr bool is_range = detail::is_range_t<Container, ElementT>::value;
template <class Container>
static constexpr bool is_any_range = detail::is_any_range_t<Container>::value;
template <class C>
constexpr auto begin(C& c) -> decltype(c.begin())
{
......@@ -355,12 +396,9 @@ using compact_size_t_typed = size_t_for<N, alignof(T)>;
template <unsigned... digits>
struct digits_to_string_literal
{
static const char value[];
static constexpr const char value[] = {('0' + digits)..., 0};
};
template <unsigned... digits>
constexpr char digits_to_string_literal<digits...>::value[] = {('0' + digits)..., 0};
template <unsigned rem, unsigned... digits>
struct number_to_string_literal_t : number_to_string_literal_t<rem / 10, rem % 10, digits...>
{
......
......@@ -169,6 +169,12 @@ template <class T>
return {e, v.derivative * e};
}
template <class T>
[[nodiscard]] constexpr fwd_diff<T> pow(fwd_diff<T> const& v, dont_deduce<T> const& p)
{
return {pow(v.value, p), v.derivative * p * pow(v.value, p - 1)};
}
template <class T>
[[nodiscard]] constexpr fwd_diff<T> log(fwd_diff<T> const& v)
{
......
......@@ -3,7 +3,9 @@
#include <typed-geometry/feature/vector.hh>
#include <typed-geometry/functions/matrix/adjugate.hh>
#include <typed-geometry/functions/matrix/compose.hh>
#include <typed-geometry/functions/matrix/covariance.hh>
#include <typed-geometry/functions/matrix/decompose.hh>
#include <typed-geometry/functions/matrix/determinant.hh>
#include <typed-geometry/functions/matrix/diag.hh>
#include <typed-geometry/functions/matrix/eigenvalues.hh>
......
......@@ -3,6 +3,8 @@
#include <typed-geometry/feature/basic.hh>
#include <typed-geometry/functions/objects/aabb.hh>
#include <typed-geometry/functions/objects/any_point.hh>
#include <typed-geometry/functions/objects/apex.hh>
#include <typed-geometry/functions/objects/area.hh>
#include <typed-geometry/functions/objects/boundary.hh>
#include <typed-geometry/functions/objects/bounds.hh>
......@@ -13,12 +15,19 @@
#include <typed-geometry/functions/objects/direction.hh>
#include <typed-geometry/functions/objects/distance.hh>
#include <typed-geometry/functions/objects/edges.hh>
#include <typed-geometry/functions/objects/faces.hh>
#include <typed-geometry/functions/objects/frustum.hh>
#include <typed-geometry/functions/objects/intersection.hh>
#include <typed-geometry/functions/objects/normal.hh>
#include <typed-geometry/functions/objects/perimeter.hh>
#include <typed-geometry/functions/objects/plane.hh>
#include <typed-geometry/functions/objects/project.hh>
#include <typed-geometry/functions/objects/rasterize.hh>
#include <typed-geometry/functions/objects/segmentize.hh>
#include <typed-geometry/functions/objects/size.hh>
#include <typed-geometry/functions/objects/tangent.hh>
#include <typed-geometry/functions/objects/triangle.hh>
#include <typed-geometry/functions/objects/triangulate.hh>
#include <typed-geometry/functions/objects/triangulation.hh>
#include <typed-geometry/functions/objects/vertices.hh>
#include <typed-geometry/functions/objects/volume.hh>
......@@ -3,6 +3,7 @@
#include <typed-geometry/detail/operators/ops_mat.hh>
#include <typed-geometry/functions/basic/mix.hh>
#include <typed-geometry/functions/basic/scalar_math.hh>
#include <typed-geometry/functions/tests/quat_tests.hh>
#include <typed-geometry/functions/vector/normalize.hh>
#include <typed-geometry/types/dir.hh>
#include <typed-geometry/types/mat.hh>
......
#pragma once
#include <typed-geometry/detail/operators.hh>
#include <typed-geometry/functions/vector/angle.hh>
#include <typed-geometry/functions/vector/cross.hh>
#include <typed-geometry/functions/vector/distance.hh>
......
......@@ -3,6 +3,7 @@
#include <typed-geometry/functions/basic/limits.hh>
#include <typed-geometry/functions/basic/scalar_math.hh>
#include <typed-geometry/types/comp.hh>
#include <typed-geometry/types/pos.hh>
#include <typed-geometry/types/size.hh>
#include <typed-geometry/types/span.hh>
......@@ -45,6 +46,27 @@ template <class T, class... Ts>
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT min_element(comp<1, ScalarT> const& p)
{
return p.comp0;
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT min_element(comp<2, ScalarT> const& p)
{
return min(p.comp0, p.comp1);
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT min_element(comp<3, ScalarT> const& p)
{
return min(p.comp0, p.comp1, p.comp2);
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT min_element(comp<4, ScalarT> const& p)
{
return min(min(p.comp0, p.comp1), min(p.comp2, p.comp3));
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT min_element(pos<1, ScalarT> const& p)
{
......@@ -108,6 +130,28 @@ template <class ScalarT>
return min(min(p.width, p.height), min(p.depth, p.w));
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT max_element(comp<1, ScalarT> const& p)
{
return p.comp0;
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT max_element(comp<2, ScalarT> const& p)
{
return max(p.comp0, p.comp1);
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT max_element(comp<3, ScalarT> const& p)
{
return max(p.comp0, p.comp1, p.comp2);
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT max_element(comp<4, ScalarT> const& p)
{
return max(max(p.comp0, p.comp1), max(p.comp2, p.comp3));
}
template <class ScalarT>
[[nodiscard]] constexpr ScalarT max_element(pos<1, ScalarT> const& p)
{
......
......@@ -16,7 +16,7 @@ template <int D>
else if constexpr (D == 4)
return c.comp0 || c.comp1 || c.comp2 || c.comp3;
else
static_assert(always_false<D>, "only up to 4D supported");
static_assert(always_false_v<D>, "only up to 4D supported");
}
template <int D>
......@@ -31,6 +31,6 @@ template <int D>
else if constexpr (D == 4)
return c.comp0 && c.comp1 && c.comp2 && c.comp3;
else
static_assert(always_false<D>, "only up to 4D supported");
static_assert(always_false_v<D>, "only up to 4D supported");
}
}
......@@ -144,6 +144,14 @@ template <class A, class B>
return a < b ? b : a;
}
template <class T>
[[nodiscard]] constexpr pair<T, T> minmax(T const& a, T const& b)
{
if (b < a)
return {b, a};
return {a, b};
}
template <class A, class B, class C>
[[nodiscard]] constexpr auto clamp(A const& a, B const& min_value, C const& max_value) -> decltype(min(max(a, min_value), max_value))
{
......@@ -278,13 +286,13 @@ template <class T>
[[nodiscard]] constexpr f32 smoothstep(f32 edge0, f32 edge1, f32 x)
{
auto t = clamp((x - edge0) / (edge1 - edge0), f32(0), f32(1));
return t * t * (f32(3) - f32(2) * t);
auto t = clamp((x - edge0) / (edge1 - edge0), 0.f, 1.f);
return t * t * (3.f - 2.f * t);
}
[[nodiscard]] constexpr f64 smoothstep(f64 edge0, f64 edge1, f64 x)
{
auto t = clamp((x - edge0) / (edge1 - edge0), f64(0), f64(1));
return t * t * (f64(3) - f64(2) * t);
auto t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}
// ==================================================================
......
......@@ -10,6 +10,8 @@
*
* - min_element
* - max_element
* - max_index
* - min_index
* - average (same as arithmetic_mean)
* - mean (same as arithmetic_mean)
* - arithmetic_mean
......@@ -39,11 +41,11 @@ template <class T = void, class RangeT, class TransformF, class ReduceF>
using U = std::decay_t<decltype(f(t(R(*it)), t(R(*it))))>;
auto const e = tg::end(values);
U r = t(R(*it));
it++;
++it;
while (it != e)
{
r = f(r, t(R(*it)));
it++;
++it;
}
return r;
}
......@@ -59,7 +61,7 @@ template <class RangeT, class KeyT>
auto min_e = it;
auto min_v = key(*it);
it++;
++it;
while (it != e)
{
auto v = key(*it);
......@@ -68,7 +70,7 @@ template <class RangeT, class KeyT>
min_v = v;
min_e = it;
}
it++;
++it;
}
return *min_e;
......@@ -84,7 +86,7 @@ template <class RangeT, class KeyT>
auto max_e = it;
auto max_v = key(*it);
it++;
++it;
while (it != e)
{
auto v = key(*it);
......@@ -93,7 +95,7 @@ template <class RangeT, class KeyT>
max_v = v;
max_e = it;
}
it++;
++it;
}
return *max_e;
......@@ -111,6 +113,63 @@ template <class RangeT, class TransformT = identity_fun>
return detail::fold_right(values, transform, [](auto&& a, auto&& b) { return max(a, b); });
}
/// returns the index of the max element
template <class RangeT, class TransformT = identity_fun>
[[nodiscard]] constexpr size_t max_index(RangeT const& values, TransformT&& transform = {})
{
TG_CONTRACT(tg::begin(values) != tg::end(values) && "values must not be empty");
size_t curr_idx = 0;
auto it = tg::begin(values);
auto const end = tg::end(values);
auto max_v = transform(*it);
size_t max_idx = curr_idx;
++it;
++curr_idx;
while (it != end)
{
auto v = transform(*it);
if (v > max_v)
{
max_v = v;
max_idx = curr_idx;
}
++it;
++curr_idx;
}
return max_idx;
}
/// returns the index of the min element
template <class RangeT, class TransformT = identity_fun>
[[nodiscard]] constexpr size_t min_index(RangeT const& values, TransformT&& transform = {})
{
TG_CONTRACT(tg::begin(values) != tg::end(values) && "values must not be empty");
size_t curr_idx = 0;
auto it = tg::begin(values);
auto const end = tg::end(values);
auto min_v = transform(*it);
size_t min_idx = curr_idx;
++it;
++curr_idx;
while (it != end)
{
auto v = transform(*it);
if (v < min_v)
{
min_v = v;
min_idx = curr_idx;
}
++it;
++curr_idx;
}
return min_idx;
}
template <class T = void, class RangeT = void, class TransformT = identity_fun>
[[nodiscard]] constexpr auto sum(RangeT const& values, TransformT&& transform = {})
{
......
#pragma once
#include <typed-geometry/detail/scalar_traits.hh>
#include <typed-geometry/types/scalars/fixed_int.hh>
#include <typed-geometry/types/scalars/fixed_uint.hh>
......@@ -30,4 +31,45 @@ constexpr fixed_uint<words>::fixed_uint(fixed_int<rhs_words> const& rhs)
if constexpr (rhs_words > 3 && words > 3)
d[3] = rhs.d[3];
}
template <int w>
struct make_unsigned_t<fixed_int<w>>
{
using type = fixed_uint<w>;
};
template <int w>
struct make_unsigned_t<fixed_int<w> const>
{
using type = fixed_uint<w> const;
};
template <int w>
struct make_unsigned_t<fixed_uint<w>>
{
using type = fixed_uint<w>;
};
template <int w>
struct make_unsigned_t<fixed_uint<w> const>
{
using type = fixed_uint<w> const;
};
template <int w>
struct make_signed_t<fixed_uint<w>>
{
using type = fixed_int<w>;
};
template <int w>
struct make_signed_t<fixed_uint<w> const>
{
using type = fixed_int<w> const;
};
template <int w>
struct make_signed_t<fixed_int<w>>
{
using type = fixed_int<w>;
};
template <int w>
struct make_signed_t<fixed_int<w> const>
{
using type = fixed_int<w> const;
};
}