Fix: 2D tri/quad vs point intersection tests edge cases #117786
|
@ -1517,19 +1517,14 @@ bool isect_point_tri_v2_cw(const float pt[2],
|
|||
|
||||
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
|
||||
{
|
||||
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v3, v1, pt) >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
float side12 = line_point_side_v2(v1, v2, pt);
|
||||
float side23 = line_point_side_v2(v2, v3, pt);
|
||||
float side31 = line_point_side_v2(v3, v1, pt);
|
||||
if (side12 >= 0.0f && side23 >= 0.0f && side31 >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v3, v1, pt) >= 0.0f)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (side12 <= 0.0f && side23 <= 0.0f && side31 <= 0.0f) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1538,25 +1533,16 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2],
|
|||
int isect_point_quad_v2(
|
||||
const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2])
|
||||
{
|
||||
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v3, v4, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v4, v1, pt) >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
float side12 = line_point_side_v2(v1, v2, pt);
|
||||
float side23 = line_point_side_v2(v2, v3, pt);
|
||||
float side34 = line_point_side_v2(v3, v4, pt);
|
||||
float side41 = line_point_side_v2(v4, v1, pt);
|
||||
if (side12 >= 0.0f && side23 >= 0.0f && side34 >= 0.0f && side41 >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v3, v4, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v4, v1, pt) >= 0.0f)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (side12 <= 0.0f && side23 <= 0.0f && side34 <= 0.0f && side41 <= 0.0f) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
TEST(math_geom, DistToLine2DSimple)
|
||||
{
|
||||
|
@ -19,3 +22,98 @@ TEST(math_geom, DistToLineSegment2DSimple)
|
|||
float distance = dist_to_line_segment_v2(p, a, b);
|
||||
EXPECT_NEAR(sqrtf(2.0f), distance, 1e-6);
|
||||
}
|
||||
|
||||
#include "BLI_rand.hh"
|
||||
#include "BLI_timeit.hh"
|
||||
|
||||
TEST(math_geom, IsectPointTri2D)
|
||||
{
|
||||
float2 tri_cw[3] = {{-2, 1}, {4, 4}, {2, -3}};
|
||||
float2 tri_ccw[3] = {{-2, 1}, {2, -3}, {4, 4}};
|
||||
|
||||
float2 inside1{0, 0};
|
||||
float2 inside2{2, 2};
|
||||
float2 inside3{2, -1};
|
||||
float2 inside4{-1, 1};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside3, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside3, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside4, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside4, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 outside1{2, 4};
|
||||
float2 outside2{-1, -1};
|
||||
float2 outside3{0, 3};
|
||||
float2 outside4{-4, 0};
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside3, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside3, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside4, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside4, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 edge1{0, 2};
|
||||
float2 edge2{1, -2};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(edge1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(edge1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(edge2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(edge2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 corner1{4, 4};
|
||||
float2 corner2{2, -3};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(corner1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(corner1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(corner2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(corner2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
}
|
||||
|
||||
TEST(math_geom, IsectPointQuad2D)
|
||||
{
|
||||
float2 quad_cw[4] = {{-2, 1}, {4, 4}, {5, 1}, {2, -3}};
|
||||
float2 quad_ccw[4] = {{-2, 1}, {2, -3}, {5, 1}, {4, 4}};
|
||||
|
||||
float2 inside1{0, 0};
|
||||
float2 inside2{2, 2};
|
||||
float2 inside3{3, -1};
|
||||
float2 inside4{-1, 1};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside3, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside3, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside4, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside4, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 outside1{2, 4};
|
||||
float2 outside2{-1, -1};
|
||||
float2 outside3{0, 3};
|
||||
float2 outside4{-4, 0};
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside3, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside3, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside4, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside4, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 edge1{0, 2};
|
||||
float2 edge2{1, -2};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(edge1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(edge1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(edge2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(edge2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 corner1{4, 4};
|
||||
float2 corner2{2, -3};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(corner1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(corner1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(corner2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(corner2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue