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;
187 template <
typename T>
188 fvec<T, 3> closest_point_on_line_to_point(
const fvec<T, 3>& lo,
const fvec<T, 3>& ld,
const fvec<T, 3>& p)
190 return lo + (dot(p - lo, ld) / dot(ld, ld)) * ld;
202 template <
typename T>
203 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)
205 fvec<T, 3> d = p - co;
206 d -= (dot(d, cn) / dot(cn, cn)) * cn;
210 q = co + (cr / l) * d;
213 template <
typename T>
214 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)
216 std::default_random_engine e;
217 std::uniform_real_distribution<T> d(-0.01f, 0.01f);
221 T dist = std::numeric_limits<T>::max();
226 while (!closest_point_on_circle_to_point(co, cn, cr, q, q)) {
227 q += fvec<T, 3>(d(e), d(e), d(e));
229 std::cerr <<
"jittering not working!" << std::endl;
230 return std::numeric_limits<T>::max();
234 q = closest_point_on_line_to_point(lo, ld, q);
235 dist = (q - q1).length();
237 std::cerr <<
"no convergence!" << std::endl;
240 return std::numeric_limits<T>::max();
242 }
while ((q0 - q).length() > 1e-6f);
259 template <
typename T>
260 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)
262 T dist = closest_point_on_line_to_circle_impl(lo, ld, co, cn, cr, q);
263 if (dist == std::numeric_limits<T>::max())
266 fvec<T, 3> lo2 = closest_point_on_line_to_point(lo, ld, co);
267 lo2 = 2.0f * lo2 - q;
269 T dist2 = cgv::math::closest_point_on_line_to_circle_impl(lo2, ld, co, cn, cr, q2);
270 if (dist2 == std::numeric_limits<float>::max())
280#include <cgv/config/lib_end.h>