55 "strconv"
66 "testing"
77
8+ "github.com/go-spatial/geom/cmp"
9+
810 "github.com/go-spatial/geom"
911)
1012
@@ -51,6 +53,71 @@ func TestSlope(t *testing.T) {
5153 t .Run (strconv .FormatInt (int64 (i ), 10 ), func (t * testing.T ) { fn (t , tc ) })
5254 }
5355}
56+ func TestIsPointOnLine (t * testing.T ) {
57+ type tcase struct {
58+ desc string
59+ point geom.Point
60+ segment geom.Line
61+ expected bool
62+ }
63+ fn := func (tc tcase ) (string , func (* testing.T )) {
64+ return fmt .Sprintf ("%v on %v" , tc .point , tc .segment ),
65+ func (t * testing.T ) {
66+ if tc .expected != IsPointOnLine (tc .point , tc .segment [0 ], tc .segment [1 ]) {
67+ t .Errorf ("expected %v, got %v" , tc .expected , ! tc .expected )
68+ }
69+ }
70+ }
71+ tests := [... ]tcase {
72+ {
73+ // Diagonal line
74+ point : geom.Point {1 , 1 },
75+ segment : geom.Line {{0 , 0 }, {1 , 10 }},
76+ },
77+ {
78+ // Vertical line
79+ point : geom.Point {1 , 1 },
80+ segment : geom.Line {{0 , 0 }, {0 , 10 }},
81+ },
82+ {
83+ // Vertical line
84+ point : geom.Point {1 , 1 },
85+ segment : geom.Line {{0 , 10 }, {10 , 10 }},
86+ },
87+ {
88+ // horizontal line
89+ point : geom.Point {1 , 1 },
90+ segment : geom.Line {{1 , 0 }, {1 , 10 }},
91+ expected : true ,
92+ },
93+ {
94+ // horizontal line
95+ point : geom.Point {1 , 100 },
96+ segment : geom.Line {{1 , 0 }, {1 , 10 }},
97+ expected : true ,
98+ },
99+ {
100+ // horizontal line
101+ point : geom.Point {1 , - 100 },
102+ segment : geom.Line {{1 , 0 }, {1 , 10 }},
103+ expected : true ,
104+ },
105+ {
106+ // horizontal line on close to the end point
107+ point : geom.Point {- 0.5 , 0 },
108+ segment : geom.Line {{1 , 0 }, {1 , 10 }},
109+ },
110+ {
111+ // horizontal line on the end point
112+ point : geom.Point {1 , 0 },
113+ segment : geom.Line {{1 , 0 }, {1 , 10 }},
114+ expected : true ,
115+ },
116+ }
117+ for _ , tc := range tests {
118+ t .Run (fn (tc ))
119+ }
120+ }
54121
55122func TestIsPointOnLineSegment (t * testing.T ) {
56123 type tcase struct {
@@ -63,7 +130,7 @@ func TestIsPointOnLineSegment(t *testing.T) {
63130 return fmt .Sprintf ("%v on %v" , tc .point , tc .segment ),
64131 func (t * testing.T ) {
65132 if tc .expected != IsPointOnLineSegment (tc .point , tc .segment ) {
66- t .Errorf ("got %v, expected %v" , ! tc .expected , tc .expected )
133+ t .Errorf ("expected %v, got %v" , tc .expected , ! tc .expected )
67134 }
68135 }
69136 }
@@ -105,3 +172,123 @@ func TestIsPointOnLineSegment(t *testing.T) {
105172 t .Run (fn (tc ))
106173 }
107174}
175+
176+ func TestIsCCW (t * testing.T ) {
177+ type tcase struct {
178+ desc string
179+ p1 , p2 , p3 geom.Point
180+ is bool
181+ }
182+ fn := func (tc tcase ) func (* testing.T ) {
183+ return func (t * testing.T ) {
184+ got := IsCCW (tc .p1 , tc .p2 , tc .p3 )
185+ if got != tc .is {
186+ t .Errorf (
187+ "%v:%v:%v, expected %v got %v" ,
188+ tc .p1 , tc .p2 , tc .p3 ,
189+ tc .is , got ,
190+ )
191+ return
192+ }
193+ }
194+ }
195+
196+ tests := []tcase {
197+ {
198+ p1 : geom.Point {0 , 0 },
199+ p2 : geom.Point {1 , 0 },
200+ p3 : geom.Point {1 , 1 },
201+ is : true ,
202+ },
203+ {
204+ p1 : geom.Point {204 , 694 },
205+ p2 : geom.Point {- 2511 , - 3640 },
206+ p3 : geom.Point {3462 , - 3640 },
207+ is : true ,
208+ },
209+ {
210+ p2 : geom.Point {204 , 694 },
211+ p3 : geom.Point {- 2511 , - 3640 },
212+ p1 : geom.Point {3462 , - 3640 },
213+ is : true ,
214+ },
215+ {
216+ p3 : geom.Point {204 , 694 },
217+ p1 : geom.Point {- 2511 , - 3640 },
218+ p2 : geom.Point {3462 , - 3640 },
219+ is : true ,
220+ },
221+ {
222+ p1 : geom.Point {- 2511 , - 3640 },
223+ p2 : geom.Point {204 , 694 },
224+ p3 : geom.Point {3462 , - 3640 },
225+ is : false ,
226+ },
227+ {
228+ p1 : geom.Point {- 2511 , 3640 },
229+ p2 : geom.Point {204 , 694 },
230+ p3 : geom.Point {3462 , - 3640 },
231+ is : false ,
232+ },
233+ }
234+
235+ for _ , tc := range tests {
236+ t .Run (tc .desc , fn (tc ))
237+ }
238+ }
239+ func TestPointOnLineAt (t * testing.T ) {
240+
241+ type tcase struct {
242+ desc string
243+ line geom.Line
244+ distance float64
245+ point geom.Point
246+ }
247+
248+ fn := func (tc tcase ) func (* testing.T ) {
249+ return func (t * testing.T ) {
250+ got := PointOnLineAt (tc .line , tc .distance )
251+ if ! cmp .GeomPointEqual (tc .point , got ) {
252+ t .Errorf ("point, expected %v, got %v" , tc .point , got )
253+ }
254+ }
255+ }
256+
257+ tests := []tcase {
258+ {
259+ desc : "simple test case" ,
260+ line : geom.Line {{0 , 0 }, {10 , 0 }},
261+ distance : 5.0 ,
262+ point : geom.Point {5 , 0 },
263+ },
264+ {
265+ line : geom.Line {{204 , 694 }, {- 2511 , - 3640 }},
266+ distance : 100 ,
267+ point : geom.Point {150.9122535714552 , 609.2551406919657 },
268+ },
269+ {
270+ line : geom.Line {{204 , 694 }, {475.500 , 8853 }},
271+ distance : 100 ,
272+ point : geom.Point {207.3257728713106 , 793.9446808730132 },
273+ },
274+ {
275+ line : geom.Line {{204 , 694 }, {369 , 793 }},
276+ distance : 100 ,
277+ point : geom.Point {289.7492925712544 , 745.4495755427527 },
278+ },
279+ {
280+ line : geom.Line {{204 , 694 }, {426 , 539 }},
281+ distance : 100 ,
282+ point : geom.Point {285.9925374282251 , 636.7529581019149 },
283+ },
284+ {
285+ line : geom.Line {{204 , 694 }, {273 , 525 }},
286+ distance : 100 ,
287+ point : geom.Point {241.79928289224065 , 601.4191476987149 },
288+ },
289+ }
290+
291+ for _ , tc := range tests {
292+ t .Run (tc .desc , fn (tc ))
293+ }
294+ }
0 commit comments