Ray đúc trong cấu hình quạt tạo ra đám mây điểm với độ cong, làm thế nào để loại bỏ độ cong?


7

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): nhập mô tả hình ảnh ở đây

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.

Câu trả lời:


9

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.

Có vấn đề của bạn, bằng cách tạo ra các tia theo cách đó, bạn đang làm một cái gì đó giống như hình chiếu hình cầu hoặc hình chiếu mắt cá, không phải là hình chiếu phối cảnh tuyến tính. Hình chiếu phi tuyến là nguồn gốc của độ cong mà bạn nhìn thấy.

Thay vào đó, để có được hình chiếu phối cảnh, về mặt khái niệm, cách suy nghĩ về nó là có một hình chữ nhật hình ảnh nổi trước máy ảnh, được chia thành các ô vuông (pixel) và bạn bắn một tia từ vị trí camera về phía giữa mỗi pixel . Trong mã, cái này trông giống như:

p = tan(horizontalFOV / 2)
q = tan(verticalFOV / 2)
for y = 0 to imageHeight - 1
    for x = 0 to imageWidth - 1
        rayDirection = Vec3f(1.0,
                             p * ((x + 0.5) / imageWidth * 2.0 - 1.0)
                             q * ((y + 0.5) / imageHeight * 2.0 - 1.0)).normalize()

Lưu ý rằng các hướng dẫn được tạo ra theo cách này không cách đều nhau trong góc (họ đang xích lại gần nhau trong góc về phía các cạnh của hình ảnh hơn tại trung tâm), nhưng họ đang cách nhau đều ở khoảng cách trên hình chữ nhật hình ảnh.


Cảm ơn Nathan! Tôi đang cố gắng mô phỏng máy quét LIDAR, vì vậy đó là lý do cho chùm tia quạt và khoảng cách góc bằng nhau. Máy quét cụ thể tôi đang mô hình hóa mô phỏng của mình sau khi có các tia laser trong cấu hình chùm quạt bên ngoài vỏ, nhưng khi các đường hồi lưu đi qua chúng được chuyển hướng từ một chùm quạt thành các chùm song song (bằng thấu kính). Tôi đang cố gắng tìm cách duy trì mô hình này để làm cho mô phỏng chính xác nhất có thể. Bất kỳ suy nghĩ như làm thế nào tôi có thể làm điều này?
Irongrave

@Irongrave Xin lỗi, tôi không biết nhiều về máy quét LIDAR. Bạn có sơ đồ hoặc một cái gì đó của thiết lập với ống kính bạn đề cập? Tôi đang có một thời gian khó hình dung nó.
Nathan Reed

Đây là hình ảnh từ sách hướng dẫn: ( imgur.com/a/czhpt )
Irongrave

1
Hóa ra tôi đã tin không chính xác 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. Bài viết của bạn đã giúp tôi đi đến kết luận cuối cùng, vì vậy cảm ơn bạn và tôi đã chọn nó làm câu trả lời vì bạn đã đúng.
Irongrave
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.