16#include "testing/testing.h"
37#define DEFAULT_TEST_ITER 8
40#define DEFAULT_TEST_POLY_NUM 12
42#define DEFAULT_TEST_RANDOM_SEED 123
45#define ROTATION_EPS 1e-6
56 for (
int p_index : points_map) {
57 points_hull[index++] = points[p_index];
91TEST(convexhull_2d, IsConvex)
104 int i_prev = points_hull.
size() - 2;
105 int i_curr = points_hull.
size() - 1;
106 for (
int i_next = 0; i_next < points_hull.
size(); i_prev = i_curr, i_curr = i_next++) {
107 EXPECT_GE(
cross_tri_v2(points_hull[i_prev], points_hull[i_curr], points_hull[i_next]), 0.0f);
117 for (
float2 &p : points) {
122 EXPECT_GE(
cross_poly_v2(
reinterpret_cast<const float (*)[2]
>(points_hull.
data()),
145TEST(convexhull_2d, Lines_AxisAligned)
148 for (
int sign_x = -1; sign_x <= 2; sign_x += 2) {
156 for (
int sign_x = -1; sign_x <= 2; sign_x += 2) {
165 for (
int sign_y = -1; sign_y <= 2; sign_y += 2) {
173 for (
int sign_y = -1; sign_y <= 2; sign_y += 2) {
186 for (
float2 &p : points) {
200 for (
float2 &p : points) {
211TEST(convexhull_2d, Lines_Diagonal)
214 const float expected[4] = {45, -45, -45, 45};
216 for (
int sign_x = -1; sign_x <= 2; sign_x += 2) {
217 for (
int sign_y = -1; sign_y <= 2; sign_y += 2) {
228 const float expected[4] = {45, -45, -45, 45};
230 for (
int sign_x = -1; sign_x <= 2; sign_x += 2) {
231 for (
int sign_y = -1; sign_y <= 2; sign_y += 2) {
234 {1.0f * sign_x, 1.0f * sign_y},
235 {2.0f * sign_x, 2.0f * sign_y},
276 points_square_diagonal,
277 points_square_aligned,
280 for (
int x = -1;
x <= 1;
x += 2) {
281 for (
int y = -1;
y <= 1;
y += 2) {
284 for (
int i = 0;
i < points.
size();
i++) {
285 points[
i] *= xy_flip;
290 points_indices.
data());
294 for (
int i = 0;
i < points_indices_num;
i++) {
295 points_hull[
i] = points[points_indices[
i]];
300 cross_poly_v2(
reinterpret_cast<float (*)[2]
>(points_hull.
data()), points_indices_num),
304 for (
int i = 1;
i < points_indices_num;
i++) {
305 EXPECT_TRUE((points_hull[0][1] == points_hull[
i][1]) ?
307 (points_hull[0][0] < points_hull[
i][0]) :
309 (points_hull[0][1] < points_hull[
i][1]));
322 for (
int i = 0;
i < points_num;
i++) {
338TEST(convexhull_2d, OctagonAxisAligned)
344 for (
int i = 0;
i < points_num;
i++) {
360TEST(convexhull_2d, OctagonNearDuplicates)
369 {-128.28127, -311.8105},
370 {-98.5207, -288.1762},
371 {-96.177475, -267.75345},
372 {-119.81172, -237.99284},
373 {-140.23453, -235.64966},
374 {-140.23453, -235.64963},
375 {-169.99509, -259.28387},
376 {-172.33832, -279.7067},
377 {-148.70407, -309.46725},
378 {-128.28127, -311.81046},
381 for (
int scale_step = -15; scale_step <= 15; scale_step += 1) {
384 if (scale_step == 0) {
387 else if (scale_step < 0) {
388 scale =
float(1.0 /
pow(10.0,
double(-scale_step)));
391 scale =
float(
pow(10.0,
double(scale_step)));
395 for (
float2 &p : points_copy) {
401 const float abs_error = scale < 10.0f ?
ROTATION_EPS : 1e-5f;
420 const int points_num_reserved = 4;
429 for (
int i = points_num_reserved;
i < points_num;
i++) {
435 for (
int i = 0;
i < points_num_reserved;
i++) {
436 std::swap(points[
i], points[rng.
get_int32(points_num)]);
440 const float2 translation = {
447 for (
float2 &p : points) {
451 p = (((p -
float2(0.5f, 0.5f)) *
size) * rot_mat) + translation;
459 constexpr float size_margin = 0.1;
472 for (
const float2 &p : points) {
476 const float2 size_result = tempmax - tempmin;
477 float area_input =
size[0] *
size[1];
478 float area_result = size_result[0] * size_result[1];
479 EXPECT_LE(area_result, area_input + 1e-6f);
490TEST(convexhull_2d, Circle)
498 for (
int i = 0;
i < points_num;
i++) {
513TEST(convexhull_2d, Random)
521 for (
int i = 0;
i < points_num;
i++) {
float BLI_convexhull_aabb_fit_points_2d(blender::Span< blender::float2 > points)
int BLI_convexhull_2d(blender::Span< blender::float2 > points, int r_points[])
static blender::Array< float2 > convexhull_points_from_map(blender::Span< float2 > points, blender::Span< int > points_map)
static float mod_inline(float a, float b)
static blender::Array< float2 > convexhull_2d_as_array(blender::Span< float2 > points)
#define DEFAULT_TEST_RANDOM_SEED
#define DEFAULT_TEST_POLY_NUM
#define DEFAULT_TEST_ITER
static float convexhull_aabb_canonical_angle(float angle)
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
float cross_poly_v2(const float verts[][2], unsigned int nr)
void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos)
#define INIT_MINMAX2(min, max)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void shuffle(MutableSpan< T > values)
constexpr int64_t size() const
AngleRadianBase< float > AngleRadian
T min(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
MatT from_rotation(const RotationT &rotation)
MatBase< float, 2, 2 > float2x2
VecBase< float, 2 > float2
TEST(compression, filter_transpose_delta)
static AngleRadianBase from_degree(const float °rees)