inline Box::length_type distance(Box const& obj, typename Box::position_type const& pos) { typedef Box::length_type length_type; boost::array<length_type, 3> x_y_z(to_internal(obj, pos)); boost::array<length_type, 3> dx_dy_dz(subtract(abs(x_y_z), obj.half_extent())); if (dx_dy_dz[0] > 0) { if (dx_dy_dz[1] > 0) { if (dx_dy_dz[2] > 0) { // Far away from box. return length(dx_dy_dz); } else { return length(array_slice<0, 2>(dx_dy_dz)); } } else { if (dx_dy_dz[2] > 0) { return std::sqrt(gsl_pow_2(dx_dy_dz[0]) + gsl_pow_2(dx_dy_dz[2])); } else { return dx_dy_dz[0]; } } } else { if (dx_dy_dz[1] > 0) { if (dx_dy_dz[2] > 0) { return length(array_slice<1, 3>(dx_dy_dz)); } else { return dx_dy_dz[1]; } } else { if (dx_dy_dz[2] > 0) { return dx_dy_dz[2]; } else { // Inside box. return std::max(std::max(dx_dy_dz[0], dx_dy_dz[1]), dx_dy_dz[2]); } } } }
inline std::pair<typename Plane<T_>::position_type, typename Plane<T_>::length_type> projected_point(Plane<T_> const& obj, typename Plane<T_>::position_type const& pos) { boost::array<typename Plane<T_>::length_type, 3> x_y_z(to_internal(obj, pos)); return std::make_pair( add(add(obj.position(), multiply(obj.unit_x(), x_y_z[0])), multiply(obj.unit_y(), x_y_z[1])), x_y_z[2]); }