@@ -135,7 +135,7 @@ export async function checkMatch(actual, expected, p5) {
135
135
width ,
136
136
height ,
137
137
{
138
- threshold : 0.6 ,
138
+ threshold : 0.35 ,
139
139
includeAA : false ,
140
140
alpha : 0.1
141
141
}
@@ -174,10 +174,15 @@ export async function checkMatch(actual, expected, p5) {
174
174
// Define significance thresholds
175
175
const MIN_CLUSTER_SIZE = 4 ; // Minimum pixels in a significant cluster
176
176
const MAX_TOTAL_DIFF_PIXELS = 40 ; // Maximum total different pixels
177
+ const MAX_LINE_SHIFT_PIXELS = 100 ;
177
178
178
179
// Determine if the differences are significant
179
- const significantClusters = clusterSizes . filter ( size => size >= MIN_CLUSTER_SIZE ) ;
180
- const significantDiffPixels = significantClusters . reduce ( ( sum , size ) => sum + size , 0 ) ;
180
+ const lineShiftClusters = clusterSizes . filter ( c => c . isLineShift && c . size > MIN_CLUSTER_SIZE ) ;
181
+ const nonLineShiftClusters = clusterSizes . filter ( c => ! c . isLineShift && c . size >= MIN_CLUSTER_SIZE ) ;
182
+
183
+ // Calculate significant differences excluding line shifts
184
+ const significantDiffPixels = nonLineShiftClusters . reduce ( ( sum , c ) => sum + c . size , 0 ) ;
185
+ const lineShiftPixels = lineShiftClusters . reduce ( ( sum , c ) => sum + c . size , 0 ) ;
181
186
182
187
// Update the diff canvas
183
188
diffCanvas . updatePixels ( ) ;
@@ -188,12 +193,12 @@ export async function checkMatch(actual, expected, p5) {
188
193
189
194
// Determine test result
190
195
const ok = (
191
- diffCount === 0 || // No differences at all
196
+ diffCount === 0 ||
192
197
(
193
- significantDiffPixels === 0 || // No significant clusters
198
+ significantDiffPixels === 0 ||
194
199
(
195
- significantDiffPixels <= MAX_TOTAL_DIFF_PIXELS && // Total different pixels within tolerance
196
- significantClusters . length <= 2 // Not too many significant clusters
200
+ ( significantDiffPixels <= MAX_TOTAL_DIFF_PIXELS ) &&
201
+ ( nonLineShiftClusters . length <= 2 ) // Not too many significant clusters
197
202
)
198
203
)
199
204
) ;
@@ -204,8 +209,7 @@ export async function checkMatch(actual, expected, p5) {
204
209
details : {
205
210
totalDiffPixels : diffCount ,
206
211
significantDiffPixels,
207
- clusters : clusterSizes ,
208
- significantClusters
212
+ clusters : clusterSizes
209
213
}
210
214
} ;
211
215
}
@@ -216,6 +220,7 @@ export async function checkMatch(actual, expected, p5) {
216
220
function findClusterSize ( pixels , startX , startY , width , height , radius , visited ) {
217
221
const queue = [ { x : startX , y : startY } ] ;
218
222
let size = 0 ;
223
+ const clusterPixels = [ ] ;
219
224
220
225
while ( queue . length > 0 ) {
221
226
const { x, y} = queue . shift ( ) ;
@@ -230,6 +235,7 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited)
230
235
// Mark as visited
231
236
visited . add ( pos ) ;
232
237
size ++ ;
238
+ clusterPixels . push ( { x, y} ) ;
233
239
234
240
// Add neighbors to queue
235
241
for ( let dy = - radius ; dy <= radius ; dy ++ ) {
@@ -248,8 +254,48 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited)
248
254
}
249
255
}
250
256
}
257
+
258
+ let isLineShift = false ;
259
+ if ( clusterPixels . length > 0 ) {
260
+ // Count pixels with limited neighbors (line-like characteristic)
261
+ let linelikePixels = 0 ;
262
+
263
+ for ( const { x, y} of clusterPixels ) {
264
+ // Count neighbors
265
+ let neighbors = 0 ;
266
+ for ( let dy = - 1 ; dy <= 1 ; dy ++ ) {
267
+ for ( let dx = - 1 ; dx <= 1 ; dx ++ ) {
268
+ if ( dx === 0 && dy === 0 ) continue ; // Skip self
269
+
270
+ const nx = x + dx ;
271
+ const ny = y + dy ;
272
+
273
+ // Skip if out of bounds
274
+ if ( nx < 0 || nx >= width || ny < 0 || ny >= height ) continue ;
275
+
276
+ const npos = ( ny * width + nx ) * 4 ;
277
+ // Check if neighbor is a diff pixel
278
+ if ( pixels [ npos ] === 255 && pixels [ npos + 1 ] === 0 && pixels [ npos + 2 ] === 0 ) {
279
+ neighbors ++ ;
280
+ }
281
+ }
282
+ }
283
+
284
+ // Line-like pixels typically have 1-2 neighbors
285
+ if ( neighbors <= 2 ) {
286
+ linelikePixels ++ ;
287
+ }
288
+ }
289
+
290
+ // If most pixels (>80%) in the cluster have ≤2 neighbors, it's likely a line shift
291
+ isLineShift = linelikePixels / clusterPixels . length > 0.8 ;
292
+ }
251
293
252
- return size ;
294
+ return {
295
+ size,
296
+ pixels : clusterPixels ,
297
+ isLineShift
298
+ } ;
253
299
}
254
300
255
301
/**
0 commit comments