File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -313,6 +313,32 @@ export class ShapeBuilder {
313313 }
314314 }
315315
316+ // Normalize nearly identical consecutive vertices to prevent tessellation artifacts
317+ // This addresses numerical precision issues in libtess when consecutive vertices
318+ // have coordinates that are almost (but not exactly) equal (e.g., differing by ~1e-8)
319+ const epsilon = 1e-6 ;
320+ for ( const contour of contours ) {
321+ const stride = this . tessyVertexSize ;
322+ for ( let i = stride ; i < contour . length ; i += stride ) {
323+ const prevX = contour [ i - stride ] ;
324+ const prevY = contour [ i - stride + 1 ] ;
325+ const prevZ = contour [ i - stride + 2 ] ;
326+ const currX = contour [ i ] ;
327+ const currY = contour [ i + 1 ] ;
328+ const currZ = contour [ i + 2 ] ;
329+
330+ if ( Math . abs ( currX - prevX ) < epsilon ) {
331+ contour [ i ] = prevX ;
332+ }
333+ if ( Math . abs ( currY - prevY ) < epsilon ) {
334+ contour [ i + 1 ] = prevY ;
335+ }
336+ if ( Math . abs ( currZ - prevZ ) < epsilon ) {
337+ contour [ i + 2 ] = prevZ ;
338+ }
339+ }
340+ }
341+
316342 const polyTriangles = this . _triangulate ( contours ) ;
317343
318344 // If there were no valid faces, we still want to use the original vertices
Original file line number Diff line number Diff line change @@ -693,4 +693,35 @@ visualSuite('WebGL', function() {
693693 screenshot ( ) ;
694694 } ) ;
695695 } ) ;
696+
697+ visualSuite ( 'Tessellation' , function ( ) {
698+ visualTest ( 'Handles nearly identical consecutive vertices' , function ( p5 , screenshot ) {
699+ p5 . createCanvas ( 100 , 100 , p5 . WEBGL ) ;
700+ p5 . pixelDensity ( 1 ) ;
701+ p5 . background ( 255 ) ;
702+ p5 . fill ( 0 ) ;
703+ p5 . noStroke ( ) ;
704+
705+ // Contours with nearly identical consecutive vertices (as can occur with textToContours)
706+ // Outer contour
707+ p5 . beginShape ( ) ;
708+ p5 . vertex ( - 30 , - 30 , 0 ) ;
709+ p5 . vertex ( 30 , - 30 , 0 ) ;
710+ p5 . vertex ( 30 , 30 , 0 ) ;
711+ p5 . vertex ( - 30 , 30 , 0 ) ;
712+
713+ // Inner contour (hole) with nearly identical vertices
714+ p5 . beginContour ( ) ;
715+ p5 . vertex ( - 10 , - 10 , 0 ) ;
716+ p5 . vertex ( - 10 , 10 , 0 ) ;
717+ // This vertex has x coordinate almost equal to previous (10.00000001 vs 10)
718+ p5 . vertex ( 10.00000001 , 10 , 0 ) ;
719+ p5 . vertex ( 10 , - 10 , 0 ) ;
720+ p5 . endContour ( ) ;
721+
722+ p5 . endShape ( p5 . CLOSE ) ;
723+
724+ screenshot ( ) ;
725+ } ) ;
726+ } ) ;
696727} ) ;
You can’t perform that action at this time.
0 commit comments