@@ -354,60 +354,61 @@ 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+ n = points .shape [0 ]
358+ lr_points = np .empty ((n , 2 , 3 ), dtype = np .float32 )
359+ lr_points [:, 0 , :] = points
360+ lr_points [:, 1 , :] = points
361+ lr_points [:, 0 , 1 ] -= y_off
362+ lr_points [:, 1 , 1 ] += y_off
363+ lr_points [:, :, 2 ] += z_off
362364
363365 # 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 , :]
366+ proj = (self ._car_space_transform @ lr_points .reshape (- 1 , 3 ).T ).T .reshape (- 1 , 2 , 3 )
368367
369368 # 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 ):
369+ z_vals = np .abs (proj [:, :, 2 ])
370+ valid_pairs = (z_vals >= 1e-6 ).all (axis = 1 )
371+ if not valid_pairs .any ():
372372 return np .empty ((0 , 2 ), dtype = np .float32 )
373373
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 , :]
374+ proj = proj [valid_pairs ]
375+
376+ screen = proj [:, :, :2 ] / proj [:, :, 2 :3 ]
377+ left_screen = screen [:, 0 , :]
378+ right_screen = screen [:, 1 , :]
377379
378380 # Define clip region bounds
379381 clip = self ._clip_region
380382 x_min , x_max = clip .x , clip .x + clip .width
381383 y_min , y_max = clip .y , clip .y + clip .height
382384
383385 # 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 )
386+ in_clip = (
387+ (left_screen [:, 0 ] >= x_min ) & (left_screen [:, 0 ] <= x_max ) &
388+ (left_screen [:, 1 ] >= y_min ) & (left_screen [:, 1 ] <= y_max ) &
389+ (right_screen [:, 0 ] >= x_min ) & (right_screen [:, 0 ] <= x_max ) &
390+ (right_screen [:, 1 ] >= y_min ) & (right_screen [:, 1 ] <= y_max )
391391 )
392- both_in_clip = left_in_clip & right_in_clip
393-
394- if not np .any (both_in_clip ):
392+ if not in_clip .any ():
395393 return np .empty ((0 , 2 ), dtype = np .float32 )
396394
397- # Select valid and clipped points
398- left_screen = left_screen [:, both_in_clip ]
399- right_screen = right_screen [:, both_in_clip ]
395+ left_screen = left_screen [in_clip ]
396+ right_screen = right_screen [in_clip ]
400397
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 ):
398+ if not allow_invert and left_screen .shape [0 ] > 1 :
399+ y_vals = left_screen [:, 1 ]
400+ keep = y_vals == np .minimum .accumulate (y_vals )
401+ if not keep .any ():
406402 return np .empty ((0 , 2 ), dtype = np .float32 )
407- left_screen = left_screen [:, keep ]
408- right_screen = right_screen [:, keep ]
403+ left_screen = left_screen [keep ]
404+ right_screen = right_screen [keep ]
405+
406+ k = left_screen .shape [0 ]
407+ tri_strip = np .empty ((k * 2 , 2 ), dtype = np .float32 )
408+ tri_strip [0 ::2 ] = left_screen
409+ tri_strip [1 ::2 ] = right_screen
409410
410- return np . vstack (( left_screen . T , right_screen [:, :: - 1 ]. T )). astype ( np . float32 )
411+ return tri_strip
411412
412413 @staticmethod
413414 def _hsla_to_color (h , s , l , a ):
0 commit comments