@@ -414,6 +414,37 @@ def test_values(self, cpp, line, dist):
414414 assert x == py_pt .x ; assert y == py_pt .y
415415
416416
417+ class TestLineStringInterpolateNormalized :
418+ """Verify interpolate_ls(ls, t, normalized=True) matches Python."""
419+ LINE = [(0 ,0 ),(10 ,0 ),(10 ,10 )] # L-shaped
420+ LINE_CURVED = [(0 ,0 ),(3 ,4 ),(6 ,0 ),(9 ,4 ),(12 ,0 )] # curved path
421+
422+ @pytest .mark .parametrize ("line,t" , [
423+ (LINE , 0.0 ), (LINE , 0.25 ), (LINE , 0.5 ), (LINE , 0.75 ), (LINE , 1.0 ),
424+ (LINE_CURVED , 0.0 ), (LINE_CURVED , 0.2 ), (LINE_CURVED , 0.5 ),
425+ (LINE_CURVED , 0.8 ), (LINE_CURVED , 1.0 ),
426+ ])
427+ def test_values (self , cpp , line , t ):
428+ x , y = cpp .interpolate_linestring (cpp .linestring (line ), t , True )
429+ py_pt = PyLineString (line ).interpolate (t , normalized = True )
430+ assert x == py_pt .x , f"x: { x } != { py_pt .x } "
431+ assert y == py_pt .y , f"y: { y } != { py_pt .y } "
432+
433+ def test_random_lines (self , cpp ):
434+ """Random lines with exact comparison."""
435+ np .random .seed (42 )
436+ for _ in range (100 ):
437+ n = np .random .randint (2 , 10 )
438+ pts = np .random .randn (n , 2 ) * 50
439+ pts [:, 0 ] += np .arange (n ) * 10
440+ line = pts .tolist ()
441+ for t in np .linspace (0 , 1 , 11 ):
442+ x , y = cpp .interpolate_linestring (cpp .linestring (line ), float (t ), True )
443+ py_pt = PyLineString (line ).interpolate (float (t ), normalized = True )
444+ assert x == py_pt .x , f"random line: x { x } != { py_pt .x } at t={ t } "
445+ assert y == py_pt .y , f"random line: y { y } != { py_pt .y } at t={ t } "
446+
447+
417448# =============================================================================
418449# Polygon accessors + same-type distance
419450# =============================================================================
0 commit comments