cgv
Loading...
Searching...
No Matches
distance.h
1#pragma once
2
3#include "fvec.h"
4#include "proximity.h"
5
7namespace cgv {
8namespace math {
9
18template <typename T, cgv::type::uint32_type N>
19T point_line_distance(const fvec<T, N>& point, const fvec<T, N>& p0, const fvec<T, N>& direction) {
20 return length(closest_point_on_line_to_point(p0, direction), point) - point);
21}
22
30template <typename T>
31T point_box_distance(const fvec<T, 3>& point, const fvec<T, 3>& extent) {
32 fvec<T, 3> q = abs(point) - T(0.5) * extent;
33 return length(max(q, T(0))) + std::min(std::max(q.x(), std::max(q.y(), q.z())), T(0));
34}
35
44template <typename T>
45T point_plane_distance(const fvec<T, 3>& point, const fvec<T, 3>& origin, const fvec<T, 3>& normal) {
46 return dot(point - origin, normal);
47};
48
58template <typename T, cgv::type::uint32_type N>
59T point_sphere_distance(const fvec<T, N>& point, const fvec<T, N>& center, T radius) {
60 return length(center - point) - radius;
61}
62
71template<typename T>
72static std::pair<T, T> point_quadratic_bezier_distance(const fvec<T, 3>& point, const fvec<T, 3>& p0, const fvec<T, 3>& p1, const fvec<T, 3>& p2) {
73 // (Copyright 2013 Inigo Quilez: https://iquilezles.org/articles/bezierbbox/ and https://www.shadertoy.com/view/ldj3Wh)
74 using vec_type = fvec<T, 3>;
75 vec_type a = p1 - p0;
76 vec_type b = p0 - T(2) * p1 + p2;
77 vec_type c = a * T(2);
78 vec_type d = p0 - point;
79
80 T kk = T(1) / dot(b, b);
81 T kx = kk * dot(a, b);
82 T ky = kk * (T(2) * dot(a, a) + dot(d, b)) / T(3);
83 T kz = kk * dot(d, a);
84
85 T dist = T(0);
86 T t = T(0);
87
88 T p = ky - kx * kx;
89 T p3 = p * p * p;
90 T q = kx * (T(2) * kx * kx - T(3) * ky) + kz;
91 T h = q * q + T(4) * p3;
92
93 if(h >= T(0)) {
94 h = std::sqrt(h);
95 fvec<T, 2> x = (vec2(h, -h) - q) / T(2);
96 fvec<T, 2> uv = sign(x) * pow(abs(x), vec2(T(1) / T(3)));
97 t = clamp(uv.x() + uv.y() - kx, T(0), T(1));
98
99 // 1 root
100 dist = sqr_length(d + (c + b * t) * t);
101 } else {
102 T z = std::sqrt(-p);
103 T v = std::acos(q / (p * z * T(2))) / T(3);
104 T m = std::cos(v);
105 T n = std::sin(v) * T(1.732050808);
106 vec_type ts = clamp(vec_type(m + m, -n - m, n - m) * z - kx, T(0), T(1));
107
108 // 3 roots, but only need two
109 T dt = sqr_length(d + (c + b * ts.x()) * ts.x());
110 dist = dt;
111 t = ts.x();
112
113 dt = sqr_length(d + (c + b * ts.y()) * ts.y());
114 if(dt < dist) {
115 dist = dt;
116 t = ts.y();
117 }
118 }
119
120 dist = sqrt(dist);
121
122 return { dist, t };
123}
124
125} // namespace math
126} // namespace cgv
the cgv namespace
Definition print.h:11
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:659