@@ -354,60 +354,58 @@ def _map_line_to_polygon(self, line: np.ndarray, y_off: float, z_off: float, max
354354 if points .shape [0 ] == 0 :
355355 return np .empty ((0 , 2 ), dtype = np .float32 )
356356
357- N = points .shape [0 ]
358- # Generate left and right 3D points in one array using broadcasting
359- offsets = np .array ([[0 , - y_off , z_off ], [0 , y_off , z_off ]], dtype = np .float32 )
360- points_3d = points [None , :, :] + offsets [:, None , :] # Shape: 2xNx3
361- points_3d = points_3d .reshape (2 * N , 3 ) # Shape: (2*N)x3
357+ lr_points = np .stack ((points , points ), axis = 1 ).astype (np .float32 )
358+ lr_points [:, 0 , 1 ] -= y_off
359+ lr_points [:, 1 , 1 ] += y_off
360+ lr_points [:, :, 2 ] += z_off
362361
363362 # Transform all points to projected space in one operation
364- proj = self ._car_space_transform @ points_3d .T # Shape: 3x(2*N)
365- proj = proj .reshape (3 , 2 , N )
366- left_proj = proj [:, 0 , :]
367- right_proj = proj [:, 1 , :]
363+ proj = (self ._car_space_transform @ lr_points .reshape (- 1 , 3 ).T ).T .reshape (- 1 , 2 , 3 )
368364
369365 # Filter points where z is sufficiently large
370- valid_proj = (np .abs (left_proj [2 ]) >= 1e-6 ) & (np .abs (right_proj [2 ]) >= 1e-6 )
371- if not np .any (valid_proj ):
366+ z_vals = np .abs (proj [:, :, 2 ])
367+ valid_pairs = (z_vals >= 1e-6 ).all (axis = 1 )
368+ if not valid_pairs .any ():
372369 return np .empty ((0 , 2 ), dtype = np .float32 )
373370
374- # Compute screen coordinates
375- left_screen = left_proj [:2 , valid_proj ] / left_proj [2 , valid_proj ][None , :]
376- right_screen = right_proj [:2 , valid_proj ] / right_proj [2 , valid_proj ][None , :]
371+ proj = proj [valid_pairs ]
372+
373+ screen = proj [:, :, :2 ] / proj [:, :, 2 :3 ]
374+ left_screen = screen [:, 0 , :]
375+ right_screen = screen [:, 1 , :]
377376
378377 # Define clip region bounds
379378 clip = self ._clip_region
380379 x_min , x_max = clip .x , clip .x + clip .width
381380 y_min , y_max = clip .y , clip .y + clip .height
382381
383382 # Filter points within clip region
384- left_in_clip = (
385- (left_screen [0 ] >= x_min ) & (left_screen [0 ] <= x_max ) &
386- (left_screen [1 ] >= y_min ) & (left_screen [1 ] <= y_max )
387- )
388- right_in_clip = (
389- (right_screen [0 ] >= x_min ) & (right_screen [0 ] <= x_max ) &
390- (right_screen [1 ] >= y_min ) & (right_screen [1 ] <= y_max )
383+ in_clip = (
384+ (left_screen [:, 0 ] >= x_min ) & (left_screen [:, 0 ] <= x_max ) &
385+ (left_screen [:, 1 ] >= y_min ) & (left_screen [:, 1 ] <= y_max ) &
386+ (right_screen [:, 0 ] >= x_min ) & (right_screen [:, 0 ] <= x_max ) &
387+ (right_screen [:, 1 ] >= y_min ) & (right_screen [:, 1 ] <= y_max )
391388 )
392- both_in_clip = left_in_clip & right_in_clip
393-
394- if not np .any (both_in_clip ):
389+ if not in_clip .any ():
395390 return np .empty ((0 , 2 ), dtype = np .float32 )
396391
397- # Select valid and clipped points
398- left_screen = left_screen [:, both_in_clip ]
399- right_screen = right_screen [:, both_in_clip ]
392+ left_screen = left_screen [in_clip ]
393+ right_screen = right_screen [in_clip ]
400394
401- # Handle Y-coordinate inversion on hills
402- if not allow_invert and left_screen .shape [1 ] > 1 :
403- y = left_screen [1 , :] # y-coordinates
404- keep = y == np .minimum .accumulate (y )
405- if not np .any (keep ):
395+ if not allow_invert and left_screen .shape [0 ] > 1 :
396+ y_vals = left_screen [:, 1 ]
397+ keep = y_vals == np .minimum .accumulate (y_vals )
398+ if not keep .any ():
406399 return np .empty ((0 , 2 ), dtype = np .float32 )
407- left_screen = left_screen [:, keep ]
408- right_screen = right_screen [:, keep ]
400+ left_screen = left_screen [keep ]
401+ right_screen = right_screen [keep ]
402+
403+ k = left_screen .shape [0 ]
404+ tri_strip = np .empty ((k * 2 , 2 ), dtype = np .float32 )
405+ tri_strip [0 ::2 ] = left_screen
406+ tri_strip [1 ::2 ] = right_screen
409407
410- return np . vstack (( left_screen . T , right_screen [:, :: - 1 ]. T )). astype ( np . float32 )
408+ return tri_strip
411409
412410 @staticmethod
413411 def _hsla_to_color (h , s , l , a ):
0 commit comments