21 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)
23 n = normalize(p - so);
37 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)
40 for (
int i = 0; i < 3; ++i) {
44 if (q[i] < -0.5f * be[i]) {
53 if (q[i] > 0.5f * be[i]) {
77 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)
79 fvec<T, 3> p_loc = p-bo;
80 bq.inverse_rotate(p_loc);
82 for (
int i = 0; i < 3; ++i) {
86 if (q[i] < -0.5f * be[i]) {
95 if (q[i] > 0.5f * be[i]) {
119 template <
typename T>
120 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)
123 T a = dot(p - co, cd) / l;
125 fvec<T, 3> q0 = co + a * cd;
126 T r0 = (p - q0).length();
129 n = (1 / r0) * (p - q0);
135 q = co + cr / r0 * (p - q0);
138 if (r0 > cr + (a - 1) * l)
139 n = (1 / r0) * (p - q0);
143 q = co + cd + p - q0;
145 q = co + cd + cr / r0 * (p - q0);
148 q = q0 + (cr / r0) * (p - q0);
149 n = (1 / r0) * (p - q0);
162 template <
typename T>
163 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)
170 if (std::abs(d) < 1e-10f)
172 fvec<T, 3> r = lo - lo2;
175 T s = (b * f - c * e) / d;
189 template <
typename T, cgv::type::u
int32_type N>
190 fvec<T, N> closest_point_on_line_to_point(
const fvec<T, N>& lo,
const fvec<T, N>& ld,
const fvec<T, N>& p)
192 return lo + (dot(p - lo, ld) / dot(ld, ld)) * ld;
204 template <
typename T>
205 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)
207 fvec<T, 3> d = p - co;
208 d -= (dot(d, cn) / dot(cn, cn)) * cn;
212 q = co + (cr / l) * d;
215 template <
typename T>
216 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)
218 std::default_random_engine e;
219 std::uniform_real_distribution<T> d(-0.01f, 0.01f);
223 T dist = std::numeric_limits<T>::max();
228 while (!closest_point_on_circle_to_point(co, cn, cr, q, q)) {
229 q += fvec<T, 3>(d(e), d(e), d(e));
231 std::cerr <<
"jittering not working!" << std::endl;
232 return std::numeric_limits<T>::max();
236 q = closest_point_on_line_to_point(lo, ld, q);
237 dist = (q - q1).length();
239 std::cerr <<
"no convergence!" << std::endl;
242 return std::numeric_limits<T>::max();
244 }
while ((q0 - q).length() > 1e-6f);
261 template <
typename T>
262 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)
264 T dist = closest_point_on_line_to_circle_impl(lo, ld, co, cn, cr, q);
265 if (dist == std::numeric_limits<T>::max())
268 fvec<T, 3> lo2 = closest_point_on_line_to_point(lo, ld, co);
269 lo2 = 2.0f * lo2 - q;
271 T dist2 = cgv::math::closest_point_on_line_to_circle_impl(lo2, ld, co, cn, cr, q2);
272 if (dist2 == std::numeric_limits<float>::max())
282#include <cgv/config/lib_end.h>