@@ -937,10 +937,14 @@ <h3>Guidelines</h3>
937937 let nonTargetFingerMovements = 0 ;
938938
939939 // Enhanced touch detection parameters
940- const TOUCH_THRESHOLD = 0.06 ; // More precise threshold
941- const MIN_DETECTION_FRAMES = 3 ; // Must detect touch for multiple frames
940+ const TOUCH_THRESHOLD = 0.08 ; // Slightly more forgiving threshold
941+ const MIN_DETECTION_FRAMES = 2 ; // Reduced from 3 for faster response
942942 const ACCURACY_BONUS_THRESHOLD = 2 ; // Max wrong touches for accuracy bonus
943943
944+ // Smoothing for visual stability
945+ let fingerPositionSmoothing = { } ;
946+ const SMOOTHING_FACTOR = 0.7 ;
947+
944948 // Initialize MediaPipe Hands
945949 function initializeHands ( ) {
946950 hands = new Hands ( {
@@ -1162,26 +1166,27 @@ <h3>Guidelines</h3>
11621166 allFingerTips . forEach ( fingerLandmark => {
11631167 const fingerTip = landmarks [ fingerLandmark ] ;
11641168
1165- // Calculate distance from thumb for all fingers
1166- const distance3D = Math . sqrt (
1169+ // Enhanced distance calculation with better weighting
1170+ const distance2D = Math . sqrt (
11671171 Math . pow ( ( thumbTip . x - fingerTip . x ) , 2 ) +
1168- Math . pow ( ( thumbTip . y - fingerTip . y ) , 2 ) +
1169- Math . pow ( ( thumbTip . z - fingerTip . z ) * 0.3 , 2 )
1172+ Math . pow ( ( thumbTip . y - fingerTip . y ) , 2 )
11701173 ) ;
11711174
1172- const distance2D = Math . sqrt (
1175+ const distance3D = Math . sqrt (
11731176 Math . pow ( ( thumbTip . x - fingerTip . x ) , 2 ) +
1174- Math . pow ( ( thumbTip . y - fingerTip . y ) , 2 )
1177+ Math . pow ( ( thumbTip . y - fingerTip . y ) , 2 ) +
1178+ Math . pow ( ( thumbTip . z - fingerTip . z ) * 0.2 , 2 ) // Reduced z-weight for stability
11751179 ) ;
11761180
1177- const distance = Math . min ( distance3D , distance2D ) ;
1181+ // Use the more reliable measure with preference for 2D
1182+ const distance = Math . min ( distance2D , distance3D * 1.1 ) ; // Slight preference for 2D
11781183
11791184 if ( distance < TOUCH_THRESHOLD ) {
11801185 currentlyTouching . add ( fingerLandmark ) ;
11811186 }
11821187
1183- // Track unwanted movements in non-target fingers
1184- if ( ! requiredFingers . has ( fingerLandmark ) && distance < 0.12 ) {
1188+ // Track unwanted movements in non-target fingers (slightly more forgiving)
1189+ if ( ! requiredFingers . has ( fingerLandmark ) && distance < 0.14 ) {
11851190 nonTargetFingerMovements ++ ;
11861191 }
11871192 } ) ;
@@ -1278,6 +1283,21 @@ <h3>Guidelines</h3>
12781283 const tip = landmarks [ landmark ] ;
12791284 if ( ! tip ) return ;
12801285
1286+ // Apply smoothing to circle positions for stability
1287+ const currentX = tip . x * canvasElement . width ;
1288+ const currentY = tip . y * canvasElement . height ;
1289+
1290+ if ( ! fingerPositionSmoothing [ landmark ] ) {
1291+ fingerPositionSmoothing [ landmark ] = { x : currentX , y : currentY } ;
1292+ }
1293+
1294+ // Smooth the position
1295+ fingerPositionSmoothing [ landmark ] . x = fingerPositionSmoothing [ landmark ] . x * SMOOTHING_FACTOR + currentX * ( 1 - SMOOTHING_FACTOR ) ;
1296+ fingerPositionSmoothing [ landmark ] . y = fingerPositionSmoothing [ landmark ] . y * SMOOTHING_FACTOR + currentY * ( 1 - SMOOTHING_FACTOR ) ;
1297+
1298+ const smoothX = fingerPositionSmoothing [ landmark ] . x ;
1299+ const smoothY = fingerPositionSmoothing [ landmark ] . y ;
1300+
12811301 let fillColor = 'rgba(128, 128, 128, 0.7)' ; // Default gray
12821302 let strokeColor = '#ffffff' ;
12831303 let radius = 12 ;
@@ -1332,7 +1352,7 @@ <h3>Guidelines</h3>
13321352 canvasCtx . shadowColor = strokeColor ;
13331353
13341354 canvasCtx . beginPath ( ) ;
1335- canvasCtx . arc ( tip . x * canvasElement . width , tip . y * canvasElement . height , radius , 0 , 2 * Math . PI ) ;
1355+ canvasCtx . arc ( smoothX , smoothY , radius , 0 , 2 * Math . PI ) ; // Use smoothed positions
13361356 canvasCtx . fill ( ) ;
13371357 canvasCtx . stroke ( ) ;
13381358
0 commit comments