| |
| |
|
|
| #pragma once |
|
|
| #include <cmath> |
| #include <type_traits> |
| #include "../half_ops.cuh" |
| #include "../geometry.h" |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
|
|
| template<typename scalar_t> |
| __qr_inline__ __qr_device__ scalar_t square(scalar_t v) { |
| return v * v; |
| } |
|
|
| template<typename accessor_t> |
| __qr_inline__ __qr_device__ auto sub_accessor(const accessor_t &a, const accessor_t &b) -> Point_<typename std::remove_pointer<typename accessor_t::PtrType>::type> { |
| return { a[0] - b[0], a[1] - b[1] }; |
| } |
|
|
| template<typename scalar_t, typename accessor_t> |
| __qr_device__ scalar_t calc_quad_width(const accessor_t &quad, |
| scalar_t outputHeight, |
| scalar_t roundFactor, |
| scalar_t maxWidth) |
| { |
| using std::max; |
| using std::ceil; |
| using std::floor; |
| typedef Point_<scalar_t> Point_t; |
|
|
| Point_t vecWidth = sub_accessor(quad[1], quad[0]); |
| Point_t vecHeight = sub_accessor(quad[3], quad[0]); |
| Point_t vecHeight2 = sub_accessor(quad[2], quad[1]); |
|
|
| scalar_t quadWidth = sqrt(dot(vecWidth)); |
| scalar_t quadHeight = sqrt(dot(vecHeight)); |
| scalar_t quadHeight2 = sqrt(dot(vecHeight2)); |
|
|
| const scalar_t sc2 = Convert<scalar_t, float>::To(2); |
| quadHeight = (quadHeight + quadHeight2) / sc2; |
|
|
| if (quadHeight < sc2) { |
| quadHeight = sc2; |
| } |
|
|
| scalar_t growthRatio = outputHeight / quadHeight; |
| quadWidth = growthRatio * quadWidth; |
|
|
| quadWidth = max(roundFactor, ceil(quadWidth / roundFactor) * roundFactor); |
|
|
| if (maxWidth > Convert<scalar_t, float>::To(0) && quadWidth > maxWidth) { |
| quadWidth = maxWidth; |
| } |
|
|
| return max(sc2, floor(quadWidth)); |
| } |
|
|
| template<typename scalar_t, typename accessor_t> |
| __qr_inline__ |
| __qr_device__ Point_<scalar_t> calc_rect_value(const accessor_t &quad, |
| const scalar_t quadWidth, |
| const scalar_t outputHeight, |
| const unsigned int x, |
| const unsigned int y, |
| const scalar_t imageWidth, |
| const scalar_t imageHeight) |
| { |
| typedef Point_<scalar_t> Point_t; |
|
|
| const Point_t pts[4] = { |
| quad[0], quad[1], quad[2], quad[3] |
| }; |
|
|
|
|
| const scalar_t scX = Convert<scalar_t, unsigned int>::RightToLeft(x); |
| const scalar_t sc1 = Convert<scalar_t, float>::RightToLeft(1); |
| const scalar_t scHalf = Convert<scalar_t, float>::RightToLeft(0.5); |
|
|
| const scalar_t fRow = (Convert<scalar_t, unsigned int>::RightToLeft(y) + scHalf) / outputHeight; |
| const scalar_t fCol = (scX + scHalf) / quadWidth; |
|
|
| |
| |
|
|
| Point_t outputPoint; |
| if (scX < quadWidth) { |
| const Point_t &q0 = pts[0]; |
| const Point_t A = pts[1] - q0; |
| const Point_t B = pts[3] - q0; |
| const Point_t C = pts[2] - pts[1]; |
|
|
| outputPoint = q0 |
| + fCol * A |
| + fRow * B |
| + (fCol * fRow) * (C - B); |
| } |
| else { |
| outputPoint = { -sc1, -sc1 }; |
| } |
|
|
| outputPoint /= Point_t{ imageWidth, imageHeight }; |
|
|
| |
| outputPoint = (Convert<scalar_t, float>::RightToLeft(2) * outputPoint) - sc1; |
|
|
| return outputPoint; |
| } |
|
|