1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2015-2018 Francois Beaune, The appleseedhq Organization
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 
29 // appleseed.foundation headers.
30 #include "foundation/math/intersection/planesegment.h"
31 #include "foundation/math/vector.h"
32 #include "foundation/utility/iostreamop.h"
33 #include "foundation/utility/test.h"
34 
35 using namespace foundation;
36 
TEST_SUITE(Foundation_Math_Intersection_PlaneSegment)37 TEST_SUITE(Foundation_Math_Intersection_PlaneSegment)
38 {
39     TEST_CASE(Clip_GivenSegmentParallelToPlaneInsideNegativeHalfSpace_ReturnsTrueAndLeavesSegmentUnchanged)
40     {
41         const Vector3d N(1.0, 0.0, 0.0);
42         const Vector3d OriginalA(-1.0, 0.0, +1.0);
43         const Vector3d OriginalB(-1.0, 0.0, -1.0);
44 
45         Vector3d a = OriginalA, b = OriginalB;
46         const bool inside = clip(N, a, b);
47 
48         EXPECT_TRUE(inside);
49         EXPECT_EQ(OriginalA, a);
50         EXPECT_EQ(OriginalB, b);
51     }
52 
53     TEST_CASE(Clip_GivenSegmentParallelToPlaneInsidePositiveHalfSpace_ReturnsFalseAndLeavesSegmentUnchanged)
54     {
55         const Vector3d N(1.0, 0.0, 0.0);
56         const Vector3d OriginalA(1.0, 0.0, +1.0);
57         const Vector3d OriginalB(1.0, 0.0, -1.0);
58 
59         Vector3d a = OriginalA, b = OriginalB;
60         const bool inside = clip(N, a, b);
61 
62         EXPECT_FALSE(inside);
63         EXPECT_EQ(OriginalA, a);
64         EXPECT_EQ(OriginalB, b);
65     }
66 
67     TEST_CASE(Clip_GivenSegmentFullyInsideNegativeHalfSpaceTowardPlane_ReturnsTrueAndLeavesSegmentUnchanged)
68     {
69         const Vector3d N(1.0, 0.0, 0.0);
70         const Vector3d OriginalA(-2.0, 0.0, 0.0);
71         const Vector3d OriginalB(-1.0, 0.0, 0.0);
72 
73         Vector3d a = OriginalA, b = OriginalB;
74         const bool inside = clip(N, a, b);
75 
76         EXPECT_TRUE(inside);
77         EXPECT_EQ(OriginalA, a);
78         EXPECT_EQ(OriginalB, b);
79     }
80 
81     TEST_CASE(Clip_GivenSegmentFullyInsideNegativeHalfSpaceAwayFromPlane_ReturnsTrueAndLeavesSegmentUnchanged)
82     {
83         const Vector3d N(1.0, 0.0, 0.0);
84         const Vector3d OriginalA(-1.0, 0.0, 0.0);
85         const Vector3d OriginalB(-2.0, 0.0, 0.0);
86 
87         Vector3d a = OriginalA, b = OriginalB;
88         const bool inside = clip(N, a, b);
89 
90         EXPECT_TRUE(inside);
91         EXPECT_EQ(OriginalA, a);
92         EXPECT_EQ(OriginalB, b);
93     }
94 
95     TEST_CASE(Clip_GivenSegmentFullyInsidePositiveHalfSpaceTowardPlane_ReturnsFalseAndLeavesSegmentUnchanged)
96     {
97         const Vector3d N(1.0, 0.0, 0.0);
98         const Vector3d OriginalA(2.0, 0.0, 0.0);
99         const Vector3d OriginalB(1.0, 0.0, 0.0);
100 
101         Vector3d a = OriginalA, b = OriginalB;
102         const bool inside = clip(N, a, b);
103 
104         EXPECT_FALSE(inside);
105         EXPECT_EQ(OriginalA, a);
106         EXPECT_EQ(OriginalB, b);
107     }
108 
109     TEST_CASE(Clip_GivenSegmentFullyInsidePositiveHalfSpaceAwayFromPlane_ReturnsFalseAndLeavesSegmentUnchanged)
110     {
111         const Vector3d N(1.0, 0.0, 0.0);
112         const Vector3d OriginalA(1.0, 0.0, 0.0);
113         const Vector3d OriginalB(2.0, 0.0, 0.0);
114 
115         Vector3d a = OriginalA, b = OriginalB;
116         const bool inside = clip(N, a, b);
117 
118         EXPECT_FALSE(inside);
119         EXPECT_EQ(OriginalA, a);
120         EXPECT_EQ(OriginalB, b);
121     }
122 
123     TEST_CASE(Clip_GivenPlaneWithNonZeroOriginAndSegmentFullyInsideNegativeHalfSpace_ReturnsTrueAndLeavesSegmentUnchanged)
124     {
125         const Vector4d Plane(1.0, 0.0, 0.0, -1.0);
126         const Vector3d OriginalA(-2.0, 0.0, 0.0);
127         const Vector3d OriginalB(1.0, 0.0, 0.0);
128 
129         Vector3d a = OriginalA, b = OriginalB;
130         const bool inside = clip(Plane, a, b);
131 
132         EXPECT_TRUE(inside);
133         EXPECT_EQ(OriginalA, a);
134         EXPECT_EQ(OriginalB, b);
135     }
136 
137     TEST_CASE(Clip_GivenSegmentStraddlingPlane1_ReturnsTrueAndClipsSegmentAgainstPlane)
138     {
139         const Vector3d N(1.0, 0.0, 0.0);
140         const Vector3d OriginalA(-1.0, 0.0, 0.0);
141         const Vector3d OriginalB(+1.0, 0.0, 0.0);
142 
143         Vector3d a = OriginalA, b = OriginalB;
144         const bool inside = clip(N, a, b);
145 
146         EXPECT_TRUE(inside);
147         EXPECT_EQ(OriginalA, a);
148         EXPECT_FEQ(Vector3d(0.0, 0.0, 0.0), b);
149     }
150 
151     TEST_CASE(Clip_GivenSegmentStraddlingPlane2_ReturnsTrueAndClipsSegmentAgainstPlane)
152     {
153         const Vector3d N(1.0, 0.0, 0.0);
154         const Vector3d OriginalA(+1.0, 0.0, 0.0);
155         const Vector3d OriginalB(-1.0, 0.0, 0.0);
156 
157         Vector3d a = OriginalA, b = OriginalB;
158         const bool inside = clip(N, a, b);
159 
160         EXPECT_TRUE(inside);
161         EXPECT_FEQ(Vector3d(0.0, 0.0, 0.0), a);
162         EXPECT_EQ(OriginalB, b);
163     }
164 
165     TEST_CASE(Clip_GivenSegmentStraddlingPlaneWithNonZeroOrigin1_ReturnsTrueAndClipsSegmentAgainstPlane)
166     {
167         const Vector4d Plane(1.0, 0.0, 0.0, -1.0);
168         const Vector3d OriginalA(-1.0, 0.0, 0.0);
169         const Vector3d OriginalB(+2.0, 0.0, 0.0);
170 
171         Vector3d a = OriginalA, b = OriginalB;
172         const bool inside = clip(Plane, a, b);
173 
174         EXPECT_TRUE(inside);
175         EXPECT_EQ(OriginalA, a);
176         EXPECT_FEQ(Vector3d(1.0, 0.0, 0.0), b);
177     }
178 
179     TEST_CASE(Clip_GivenSegmentStraddlingPlaneWithNonZeroOrigin2_ReturnsTrueAndClipsSegmentAgainstPlane)
180     {
181         const Vector4d Plane(1.0, 0.0, 0.0, -1.0);
182         const Vector3d OriginalA(+2.0, 0.0, 0.0);
183         const Vector3d OriginalB(-1.0, 0.0, 0.0);
184 
185         Vector3d a = OriginalA, b = OriginalB;
186         const bool inside = clip(Plane, a, b);
187 
188         EXPECT_TRUE(inside);
189         EXPECT_FEQ(Vector3d(1.0, 0.0, 0.0), a);
190         EXPECT_EQ(OriginalB, b);
191     }
192 }
193