Tôi đang cố gắng thực hiện kiểm tra giao cắt bằng cách sử dụng phương pháp truyền tia (không chắc là thuật ngữ chính xác vì vậy xin vui lòng tha thứ cho tôi nếu không) và xuất ra các giao điểm dưới dạng đám mây điểm và đám mây điểm chỉ hiển thị độ cong (chỉ trên trục Z, đám mây điểm hoàn toàn bằng phẳng trên trục Y và trục hoành trong hình ảnh này là trục X):
Tôi đã mượn các khái niệm từ trang Scratchapixel, cụ thể là http://scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection .
Về cơ bản, tôi đang tạo ra 16 tia, tất cả đều có cùng một vectơ gốc. Các vectơ chỉ hướng bắt đầu ở +15 độ trên mặt phẳng YZ và tiếp tục tăng từ -2 độ xuống -15. Tôi có một hộp giới hạn căn chỉnh trục mà tôi đang kiểm tra giao lộ. Tôi sử dụng một biến đổi xoay để xoay 16 tia CCW quanh trục Z. Tôi đang thực hiện kiểm tra giao nhau cho tất cả 16 tia mỗi 0,1 độ và nếu nó trở về đúng, tôi thêm điểm vào đám mây điểm.
Đây là mã giao lộ của tôi:
bool test_intersect(Box b, Ray r, Vec3f& intersect_point)
{
float txmin = 0.0f, txmax = 0.0f, tymin = 0.0f, tymax = 0.0f, tzmin = 0.0f, tzmax = 0.0f;
float t_min = 0.0f, t_max = 0.0f, t = 0.0f;
// Determine inverse direction of ray to alleviate 0 = -0 issues
Vec3f inverse_direction(1 / r.direction.x, 1 / r.direction.y, 1 / r.direction.z);
// Solving box_min/box_max0 = O + Dt
txmin = (b.box_min.x - r.origin.x) * inverse_direction.x;
txmax = (b.box_max.x - r.origin.x) * inverse_direction.x;
tymin = (b.box_min.y - r.origin.y) * inverse_direction.y;
tymax = (b.box_max.y - r.origin.y) * inverse_direction.y;
tzmin = (b.box_min.z - r.origin.z) * inverse_direction.z;
tzmax = (b.box_max.z - r.origin.z) * inverse_direction.z;
// Depending on direction of ray tmin may > tmax, so we may need to swap
if (txmin > txmax) std::swap(txmin, txmax);
if (tymin > tymax) std::swap(tymin, tymax);
if (tzmin > tzmax) std::swap(tzmin, tzmax);
t_min = txmin;
t_max = txmax;
// If t-value of a min is greater than t-value of max,
// we missed the object in that plane.
if ((t_min > tymax) || (tymin > t_max))
return false;
if (tymin > t_min)
t_min = tymin;
if (tymax < t_max)
t_max = tymax;
if ((t_min > tzmax) || (tzmin > t_max))
return false;
if (tzmin > t_min)
t_min = tzmin;
if (tzmax < t_max)
t_max = tzmax;
if (t_min > 0)
t = t_min;
else
if (t_max > 0)
t = t_max;
else
return false;
intersect_point.x = r.origin.x + r.direction.x * t;
intersect_point.y = r.origin.y + r.direction.y * t;
intersect_point.z = r.origin.z + r.direction.z * t;
return true;
}
Và vòng quay của tôi:
// Rotation around z axis, for rotating array and checking beam intersections
void transform_rotate_z(Vec3f& in_vector, float angle)
{
float radians = angle * (M_PI / 180);
float result_x = cos(radians) * in_vector.x + -sin(radians) * in_vector.y;
float result_y = sin(radians) * in_vector.x + cos(radians) * in_vector.y;
in_vector.x = result_x;
in_vector.y = result_y;
}
Tôi đã thử trí não khá lâu nhưng dường như tôi không thể xác định làm thế nào tôi có thể ngăn chặn độ cong này, tôi chắc chắn rằng tôi đang xem xét một thứ đơn giản. Tôi sẽ biết ơn bất kỳ sự giúp đỡ nào bạn có thể cung cấp.
EDIT 18/9/16: Hóa ra tôi đã tin sai rằng các đơn vị LIDAR vật lý có một số cách thuật toán "làm thẳng" ra các đường cong, đó không phải là trường hợp! Đầu ra được cho là trông giống như hình trên.