20 void closest_point_on_sphere_to_point(
const fvec<T, 3>& so, T sr,
const fvec<T, 3>& p, fvec<T, 3>& q, fvec<T, 3>& n)
22 n = normalize(p - so);
36 void closest_point_on_box_to_point(
const fvec<T, 3>& bo,
const fvec<T, 3>& be,
const fvec<T, 3>& p, fvec<T, 3>& q, fvec<T, 3>& n)
39 for (
int i = 0; i < 3; ++i) {
43 if (q[i] < -0.5f * be[i]) {
52 if (q[i] > 0.5f * be[i]) {
76 void closest_point_on_box_to_point(
const fvec<T, 3>& bo,
const fvec<T, 3>& be,
const quaternion<T>& bq,
const fvec<T, 3>& p, fvec<T, 3>& q, fvec<T, 3>& n)
78 fvec<T, 3> p_loc = p-bo;
79 bq.inverse_rotate(p_loc);
81 for (
int i = 0; i < 3; ++i) {
85 if (q[i] < -0.5f * be[i]) {
94 if (q[i] > 0.5f * be[i]) {
118 template <
typename T>
119 void closest_point_on_cylinder_to_point(
const fvec<T, 3>& co,
const fvec<T, 3>& cd, T cr,
const fvec<T, 3>& p, fvec<T, 3>& q, fvec<T, 3>& n)
122 T a = dot(p - co, cd) / l;
124 fvec<T, 3> q0 = co + a * cd;
125 T r0 = (p - q0).length();
128 n = (1 / r0) * (p - q0);
134 q = co + cr / r0 * (p - q0);
137 if (r0 > cr + (a - 1) * l)
138 n = (1 / r0) * (p - q0);
142 q = co + cd + p - q0;
144 q = co + cd + cr / r0 * (p - q0);
147 q = q0 + (cr / r0) * (p - q0);
148 n = (1 / r0) * (p - q0);
161 template <
typename T>
162 bool closest_point_on_line_to_line(
const fvec<T, 3>& lo,
const fvec<T, 3>& ld,
const fvec<T, 3>& lo2,
const fvec<T, 3>& ld2, fvec<T, 3>& q)
169 if (std::abs(d) < 1e-10f)
171 fvec<T, 3> r = lo - lo2;
174 T s = (b * f - c * e) / d;
188 template <
typename T, cgv::type::u
int32_type N>
189 fvec<T, N> closest_point_on_line_to_point(
const fvec<T, N>& lo,
const fvec<T, N>& ld,
const fvec<T, N>& p)
191 return lo + (dot(p - lo, ld) / dot(ld, ld)) * ld;
203 template <
typename T>
204 bool closest_point_on_circle_to_point(
const fvec<T, 3>& co,
const fvec<T, 3>& cn, T cr,
const fvec<T, 3>& p, fvec<T, 3>& q)
206 fvec<T, 3> d = p - co;
207 d -= (dot(d, cn) / dot(cn, cn)) * cn;
211 q = co + (cr / l) * d;
214 template <
typename T>
215 T closest_point_on_line_to_circle_impl(
const fvec<T, 3>& lo,
const fvec<T, 3>& ld,
const fvec<T, 3>& co,
const fvec<T, 3>& cn, T cr, fvec<T, 3>& q,
int* iter_ptr = 0)
217 std::default_random_engine e;
218 std::uniform_real_distribution<T> d(-0.01f, 0.01f);
222 T dist = std::numeric_limits<T>::max();
227 while (!closest_point_on_circle_to_point(co, cn, cr, q, q)) {
228 q += fvec<T, 3>(d(e), d(e), d(e));
230 std::cerr <<
"jittering not working!" << std::endl;
231 return std::numeric_limits<T>::max();
235 q = closest_point_on_line_to_point(lo, ld, q);
236 dist = (q - q1).length();
238 std::cerr <<
"no convergence!" << std::endl;
241 return std::numeric_limits<T>::max();
243 }
while ((q0 - q).length() > 1e-6f);
260 template <
typename T>
261 T closest_point_on_line_to_circle(
const fvec<T, 3>& lo,
const fvec<T, 3>& ld,
const fvec<T, 3>& co,
const fvec<T, 3>& cn, T cr, fvec<T, 3>& q,
int* iter_ptr = 0)
263 T dist = closest_point_on_line_to_circle_impl(lo, ld, co, cn, cr, q);
264 if (dist == std::numeric_limits<T>::max())
267 fvec<T, 3> lo2 = closest_point_on_line_to_point(lo, ld, co);
268 lo2 = 2.0f * lo2 - q;
270 T dist2 = cgv::math::closest_point_on_line_to_circle_impl(lo2, ld, co, cn, cr, q2);
271 if (dist2 == std::numeric_limits<float>::max())
281#include <cgv/config/lib_end.h>