26 #include <fmt/format.h>
27 #include <Eigen/Geometry>
30 namespace cloe::utility {
38 Point rotate_point(
const Point& point,
double angle) {
39 return Point{std::cos(angle) * point.x - std::sin(angle) * point.y,
40 std::sin(angle) * point.x + std::cos(angle) * point.y};
59 std::vector<Point> calc_corner_points(
double fov,
double offset,
double clip_far) {
60 std::vector<Point> ret_points;
67 ret_points.push_back(p0);
69 p1.x = clip_far * std::cos(-fov / 2.0);
70 p2.x = clip_far * std::cos(fov / 2.0);
72 p1.y = clip_far * std::sin(-fov / 2.0);
73 p2.y = clip_far * std::sin(fov / 2.0);
75 p1 = rotate_point(p1, offset);
76 p2 = rotate_point(p2, offset);
78 ret_points.push_back(p1);
79 ret_points.push_back(p2);
86 bool is_left(Point a, Point b, Point c) {
87 return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) > 0;
90 bool is_inside_fov(
double fov,
bool is_left_0_p1,
bool is_left_0_p2, std::string error_message) {
91 bool is_inside_fov =
false;
92 if (fov >= M_PI && fov <= 2 * M_PI) {
95 is_inside_fov = !(!is_left_0_p1 && is_left_0_p2);
96 }
else if (fov > 0.0 && fov < M_PI) {
98 is_inside_fov = is_left_0_p1 && !is_left_0_p2;
100 throw std::runtime_error(error_message);
102 return is_inside_fov;
105 bool is_point_inside_frustum(
const cloe::Frustum& frustum,
const Eigen::Vector3d& point) {
110 auto corner_points_x_y_plane =
111 calc_corner_points(frustum.fov_h, frustum.offset_h, frustum.clip_far);
112 auto corner_points_x_z_plane =
113 calc_corner_points(frustum.fov_v, frustum.offset_v, frustum.clip_far);
117 is_left(corner_points_x_y_plane[0], corner_points_x_y_plane[1], Point{point.x(), point.y()});
119 is_left(corner_points_x_y_plane[0], corner_points_x_y_plane[2], Point{point.x(), point.y()});
121 bool is_inside_fov_xy =
122 is_inside_fov(frustum.fov_h, is_left_0_p1, is_left_0_p2,
123 fmt::format(
"The field of view in horizontal direction of your function is not "
124 "in the expected range of (0, 2*PI]. The value we got was {}",
129 is_left(corner_points_x_z_plane[0], corner_points_x_z_plane[1], Point{point.z(), point.x()});
131 is_left(corner_points_x_z_plane[0], corner_points_x_z_plane[2], Point{point.z(), point.x()});
133 bool is_inside_fov_xz =
134 is_inside_fov(frustum.fov_v, is_left_0_p1, is_left_0_p2,
135 fmt::format(
"The field of view in vertical direction of your function is not "
136 "in the expected range of (0, 2*PI]. The value we got was {}",
140 if (is_inside_fov_xy && is_inside_fov_xz) {
142 std::sqrt(std::pow(point.x(), 2) + std::pow(point.y(), 2) + std::pow(point.z(), 2));
144 if (distance >= frustum.clip_near && distance < frustum.clip_far) {
Definition: frustum.hpp:37
Definition: frustum_culling.hpp:32