BLI_convexhull_2d: adjust order of edge iteration
Begin testing the edge edge between indices [0, 1] indices, instead of [last, 0]. This only ever makes a difference as a tie breaker, where [0, 1] is now prioritized. This minor change simplifies further optimizations.
This commit is contained in:
parent
c76eed6717
commit
7c4b2ec722
|
@ -233,17 +233,18 @@ int BLI_convexhull_2d(const float (*points)[2], const int points_num, int r_poin
|
|||
* \{ */
|
||||
|
||||
#if defined(USE_BRUTE_FORCE_ASSERT) && !defined(NDEBUG)
|
||||
static float convexhull_aabb_fit_hull_2d_brute_force(const float (*points_hull)[2],
|
||||
int points_hull_num)
|
||||
static float2 convexhull_aabb_fit_hull_2d_brute_force(const float (*points_hull)[2],
|
||||
int points_hull_num)
|
||||
{
|
||||
float area_best = FLT_MAX;
|
||||
float2 sincos_best = {0.0f, 1.0f}; /* Track the best angle as a unit vector, delaying `atan2`. */
|
||||
|
||||
for (int i = 0, i_prev = points_hull_num - 1; i < points_hull_num; i_prev = i++) {
|
||||
for (int i = 0; i < points_hull_num; i++) {
|
||||
const int i_next = (i + 1) % points_hull_num;
|
||||
/* 2D rotation matrix. */
|
||||
float dvec_length = 0.0f;
|
||||
const float2 sincos = math::normalize_and_get_length(
|
||||
float2(points_hull[i]) - float2(points_hull[i_prev]), dvec_length);
|
||||
float2(points_hull[i_next]) - float2(points_hull[i]), dvec_length);
|
||||
if (UNLIKELY(dvec_length == 0.0f)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -274,7 +275,7 @@ static float convexhull_aabb_fit_hull_2d_brute_force(const float (*points_hull)[
|
|||
}
|
||||
}
|
||||
|
||||
return (area_best != FLT_MAX) ? float(atan2(sincos_best[0], sincos_best[1])) : 0.0f;
|
||||
return sincos_best;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -337,11 +338,12 @@ static float convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], int poin
|
|||
/* Initialize to zero because the first pass uses the first index to set the bounds. */
|
||||
blender::Bounds<int> bounds_index[2] = {{0, 0}, {0, 0}};
|
||||
|
||||
for (int i = 0, i_prev = points_hull_num - 1; i < points_hull_num; i_prev = i++) {
|
||||
for (int i = 0; i < points_hull_num; i++) {
|
||||
const int i_next = (i + 1) % points_hull_num;
|
||||
/* 2D rotation matrix. */
|
||||
float dvec_length = 0.0f;
|
||||
const float2 sincos = math::normalize_and_get_length(
|
||||
float2(points_hull[i]) - float2(points_hull[i_prev]), dvec_length);
|
||||
float2(points_hull[i_next]) - float2(points_hull[i]), dvec_length);
|
||||
if (UNLIKELY(dvec_length == 0.0f)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -406,8 +408,11 @@ static float convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], int poin
|
|||
#if defined(USE_BRUTE_FORCE_ASSERT) && !defined(NDEBUG)
|
||||
{
|
||||
/* Ensure the optimized result matches the brute-force version. */
|
||||
const float angle_test = convexhull_aabb_fit_hull_2d_brute_force(points_hull, points_hull_num);
|
||||
BLI_assert(angle == angle_test);
|
||||
const float2 sincos_test = convexhull_aabb_fit_hull_2d_brute_force(points_hull,
|
||||
points_hull_num);
|
||||
if (sincos_best != sincos_test) {
|
||||
BLI_assert(sincos_best == sincos_test);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
for (int sign_x = -1; sign_x <= 2; sign_x += 2) {
|
||||
blender::Array<float2> points = {{0.0f, 0.0f}, {1.0f * sign_x, 0.0}};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(-90.0f)),
|
||||
float(math::AngleRadian::from_degree(90.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
for (int sign_x = -1; sign_x <= 2; sign_x += 2) {
|
||||
blender::Array<float2> points = {{0.0f, 0.0f}, {1.0f * sign_x, 0.0}, {2.0f * sign_x, 0.0}};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(-90.0f)),
|
||||
float(math::AngleRadian::from_degree(90.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
for (int sign_y = -1; sign_y <= 2; sign_y += 2) {
|
||||
blender::Array<float2> points = {{0.0f, 0.0f}, {0.0f, 1.0f * sign_y}};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(180.0f)),
|
||||
float(math::AngleRadian::from_degree(0.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
for (int sign_y = -1; sign_y <= 2; sign_y += 2) {
|
||||
blender::Array<float2> points = {{0.0f, 0.0f}, {0.0f, 1.0f * sign_y}, {0.0f, 2.0f * sign_y}};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(180.0f)),
|
||||
float(math::AngleRadian::from_degree(0.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
p[0] = 0.0;
|
||||
}
|
||||
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points), M_PI, ROTATION_EPS);
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points), 0.0f, ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
}
|
||||
|
||||
blender::Array<float2> points_hull = convexhull_2d_as_array(points);
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points_hull), M_PI, ROTATION_EPS);
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points_hull), 0.0f, ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ TEST(convexhull_2d, Lines_AxisAligned)
|
|||
TEST(convexhull_2d, Lines_Diagonal)
|
||||
{
|
||||
{ /* Diagonal line (2 points). */
|
||||
const float expected[4] = {-135, 135, 135, -135};
|
||||
const float expected[4] = {45, -45, -45, 45};
|
||||
int index = 0;
|
||||
for (int sign_x = -1; sign_x <= 2; sign_x += 2) {
|
||||
for (int sign_y = -1; sign_y <= 2; sign_y += 2) {
|
||||
|
@ -223,7 +223,7 @@ TEST(convexhull_2d, Lines_Diagonal)
|
|||
}
|
||||
|
||||
{ /* Diagonal line (3 points). */
|
||||
const float expected[4] = {-135, 135, 135, -135};
|
||||
const float expected[4] = {45, -45, -45, 45};
|
||||
int index = 0;
|
||||
for (int sign_x = -1; sign_x <= 2; sign_x += 2) {
|
||||
for (int sign_y = -1; sign_y <= 2; sign_y += 2) {
|
||||
|
@ -251,7 +251,7 @@ TEST(convexhull_2d, Simple)
|
|||
{1.0f, 0.0f},
|
||||
};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(135.0f)),
|
||||
float(math::AngleRadian::from_degree(45.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ TEST(convexhull_2d, Simple)
|
|||
{1.0f, -1.0f},
|
||||
};
|
||||
EXPECT_NEAR(convexhull_2d_aabb_fit_points_2d(points),
|
||||
float(math::AngleRadian::from_degree(180.0f)),
|
||||
float(math::AngleRadian::from_degree(90.0f)),
|
||||
ROTATION_EPS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue