@@ -236,12 +236,10 @@ export class GapFillSolver extends BaseSolver {
236236 }
237237
238238 private stepCheckUnoccupied ( ) : void {
239- // Find all unoccupied sections at once (can be broken down further if needed)
240239 const primaryEdge = this . state . currentPrimaryEdge !
241240 this . state . currentUnoccupiedSections =
242241 this . findUnoccupiedSections ( primaryEdge )
243242
244- // Move to placing expansion points
245243 this . state . phase = "PLACE_EXPANSION_POINTS"
246244 }
247245
@@ -266,15 +264,80 @@ export class GapFillSolver extends BaseSolver {
266264 const point =
267265 this . state . currentExpansionPoints [ this . state . currentExpansionIndex ] !
268266
269- // TODO: Actually expand the point into a rectangle
270- // For now, just move to next point
267+ const filledRect = this . expandPointToRect ( point )
268+ if ( filledRect && ! this . overlapsExistingFill ( filledRect ) ) {
269+ this . state . filledRects . push ( filledRect )
270+ }
271271
272272 this . state . currentExpansionIndex ++
273273 } else {
274274 this . moveToNextEdge ( )
275275 }
276276 }
277277
278+ private overlapsExistingFill ( candidate : Placed3D ) : boolean {
279+ for ( const existing of this . state . filledRects ) {
280+ const sharedLayers = candidate . zLayers . filter ( ( z ) =>
281+ existing . zLayers . includes ( z ) ,
282+ )
283+ if ( sharedLayers . length === 0 ) continue
284+
285+ const overlapX =
286+ Math . max ( candidate . rect . x , existing . rect . x ) <
287+ Math . min (
288+ candidate . rect . x + candidate . rect . width ,
289+ existing . rect . x + existing . rect . width ,
290+ )
291+ const overlapY =
292+ Math . max ( candidate . rect . y , existing . rect . y ) <
293+ Math . min (
294+ candidate . rect . y + candidate . rect . height ,
295+ existing . rect . y + existing . rect . height ,
296+ )
297+
298+ if ( overlapX && overlapY ) {
299+ return true
300+ }
301+ }
302+
303+ return false
304+ }
305+
306+ private expandPointToRect ( point : ExpansionPoint ) : Placed3D | null {
307+ const section = point . section
308+ const edge = section . edge
309+
310+ const nearbyEdge = this . state . currentNearbyEdges [ 0 ]
311+ if ( ! nearbyEdge ) return null
312+
313+ let rect : { x : number ; y : number ; width : number ; height : number }
314+
315+ if ( Math . abs ( edge . normal . x ) > 0.5 ) {
316+ const x1 = Math . min ( edge . x1 , nearbyEdge . x1 )
317+ const x2 = Math . max ( edge . x1 , nearbyEdge . x1 )
318+ rect = {
319+ x : x1 ,
320+ y : section . y1 ,
321+ width : x2 - x1 ,
322+ height : section . y2 - section . y1 ,
323+ }
324+ } else {
325+ const y1 = Math . min ( edge . y1 , nearbyEdge . y1 )
326+ const y2 = Math . max ( edge . y1 , nearbyEdge . y1 )
327+ rect = {
328+ x : section . x1 ,
329+ y : y1 ,
330+ width : section . x2 - section . x1 ,
331+ height : y2 - y1 ,
332+ }
333+ }
334+
335+ return {
336+ rect,
337+ zLayers : [ ...point . zLayers ] ,
338+ }
339+ }
340+
278341 private moveToNextEdge ( ) : void {
279342 this . state . currentEdgeIndex ++
280343 this . state . phase = "SELECT_PRIMARY_EDGE"
@@ -372,7 +435,7 @@ export class GapFillSolver extends BaseSolver {
372435 height : placed . rect . height ,
373436 fill : "#f3f4f6" ,
374437 stroke : "#9ca3af" ,
375- label : "existing" ,
438+ label : `input rect\npos: ( ${ placed . rect . x . toFixed ( 2 ) } , ${ placed . rect . y . toFixed ( 2 ) } )\nsize: ${ placed . rect . width . toFixed ( 2 ) } × ${ placed . rect . height . toFixed ( 2 ) } \nz: [ ${ placed . zLayers . join ( ", " ) } ]` ,
376439 } )
377440 }
378441
@@ -386,33 +449,43 @@ export class GapFillSolver extends BaseSolver {
386449 ] ,
387450 strokeColor : "#3b82f6" ,
388451 strokeWidth : 0.08 ,
389- label : " primary edge" ,
452+ label : ` primary edge ( ${ e . side } )\n( ${ e . x1 . toFixed ( 2 ) } , ${ e . y1 . toFixed ( 2 ) } ) → ( ${ e . x2 . toFixed ( 2 ) } , ${ e . y2 . toFixed ( 2 ) } )\nnormal: ( ${ e . normal . x } , ${ e . normal . y } )\nz: [ ${ e . zLayers . join ( ", " ) } ]` ,
390453 } )
391454 }
392455
393456 // Highlight nearby edges (orange)
394457 for ( const edge of this . state . currentNearbyEdges ) {
458+ const distance = this . state . currentPrimaryEdge
459+ ? this . distanceBetweenEdges (
460+ this . state . currentPrimaryEdge ,
461+ edge ,
462+ ) . toFixed ( 2 )
463+ : "?"
395464 lines . push ( {
396465 points : [
397466 { x : edge . x1 , y : edge . y1 } ,
398467 { x : edge . x2 , y : edge . y2 } ,
399468 ] ,
400469 strokeColor : "#f97316" ,
401470 strokeWidth : 0.06 ,
402- label : " nearby edge" ,
471+ label : ` nearby edge ( ${ edge . side } )\n( ${ edge . x1 . toFixed ( 2 ) } , ${ edge . y1 . toFixed ( 2 ) } ) → ( ${ edge . x2 . toFixed ( 2 ) } , ${ edge . y2 . toFixed ( 2 ) } )\ndist: ${ distance } mm\nz: [ ${ edge . zLayers . join ( ", " ) } ]` ,
403472 } )
404473 }
405474
406475 // Highlight unoccupied sections (green)
407476 for ( const section of this . state . currentUnoccupiedSections ) {
477+ const length = Math . sqrt (
478+ Math . pow ( section . x2 - section . x1 , 2 ) +
479+ Math . pow ( section . y2 - section . y1 , 2 ) ,
480+ )
408481 lines . push ( {
409482 points : [
410483 { x : section . x1 , y : section . y1 } ,
411484 { x : section . x2 , y : section . y2 } ,
412485 ] ,
413486 strokeColor : "#10b981" ,
414487 strokeWidth : 0.04 ,
415- label : " unoccupied" ,
488+ label : ` unoccupied section\n( ${ section . x1 . toFixed ( 2 ) } , ${ section . y1 . toFixed ( 2 ) } ) → ( ${ section . x2 . toFixed ( 2 ) } , ${ section . y2 . toFixed ( 2 ) } )\nlength: ${ length . toFixed ( 2 ) } mm\nrange: ${ ( section . start * 100 ) . toFixed ( 0 ) } %- ${ ( section . end * 100 ) . toFixed ( 0 ) } %` ,
416489 } )
417490 }
418491
@@ -423,7 +496,7 @@ export class GapFillSolver extends BaseSolver {
423496 y : point . y ,
424497 fill : "#a855f7" ,
425498 stroke : "#7e22ce" ,
426- label : "expand" ,
499+ label : `expansion point\npos: ( ${ point . x . toFixed ( 2 ) } , ${ point . y . toFixed ( 2 ) } )\nz: [ ${ point . zLayers . join ( ", " ) } ]` ,
427500 } as any )
428501 }
429502
@@ -438,7 +511,7 @@ export class GapFillSolver extends BaseSolver {
438511 height : placed . rect . height ,
439512 fill : "#d1fae5" ,
440513 stroke : "#10b981" ,
441- label : " filled gap" ,
514+ label : ` filled gap\npos: ( ${ placed . rect . x . toFixed ( 2 ) } , ${ placed . rect . y . toFixed ( 2 ) } )\nsize: ${ placed . rect . width . toFixed ( 2 ) } × ${ placed . rect . height . toFixed ( 2 ) } \nz: [ ${ placed . zLayers . join ( ", " ) } ]` ,
442515 } )
443516 }
444517
0 commit comments