Voici une solution vectorielle. Je ne l'ai pas essayé, mais cela semble bien conceptuellement.
Théorie
Je suppose que vous avez stocké la forme sous forme de segments de ligne. Voici la lettre A représentée par trois segments de ligne.
J'ai supposé que les chemins dans le dessin de l'utilisateur sont stockés sous forme de listes de points.
Nous pouvons «gonfler» ces segments de ligne pour permettre une marge d'erreur lors de la vérification de la proximité : si le chemin tracé par l'utilisateur est proche de la marge d'erreur de lignes correcte.
Mais cela ne suffit pas. Nous devons également vérifier la couverture : si le dessin de l'utilisateur "recouvre" une grande partie de la forme. Ces dessins sont mauvais, car même s'ils s'inscrivent dans la marge d'erreur, il leur manque une partie de la lettre:
Si nous vérifions ces deux choses, nous pouvons approximer si le dessin du joueur est bon.
la mise en oeuvre
Vérifier la proximité signifie simplement pour chaque point de chemin utilisateur, trouver la distance entre cela et chaque ligne constituant la lettre, prendre le plus bas et vérifier qu'elle est inférieure à la marge d'erreur.
La vérification de la couverture est plus compliquée, mais vous pouvez obtenir une très bonne approximation avec les mathématiques vectorielles si pour chaque segment de ligne, vous trouvez le chemin dessiné par l'utilisateur le plus proche (vert) et projetez ses parties (vert foncé) sur ce segment de ligne (noir), puis vérifiez si les vecteurs projetés (en bleu) le couvrent:
Pour projeter un vecteur a
sur un autre vecteur b
, faites
projection = dotProduct(a, b) / lengthSquared(b) * b
où dotProduct
calcule le produit scalaire des deux vecteurs et lengthSquared
correspond à ce à quoi il ressemble. Essentiellement, cela trouve la valeur scalaire de combien a
va dans b
la direction de et multiplie b
par celle-ci pour obtenir un vecteur dans la même direction. (Le didacticiel A sur la détection des collisions de Metanet Software en offre une belle visualisation dans l' annexe A § projection .)
La direction du vecteur projeté peut ne pas être réellement importante. Si vous additionnez simplement les longueurs des vecteurs projetés et les comparez à la longueur totale du segment de ligne, cela vous indiquera quelle fraction est couverte. (Sauf dans les cas étranges - voir § Limitations ci-dessous).
Dans l'image ci-dessus, le chemin couvrirait environ la moitié du segment. Vous pouvez choisir n'importe quelle valeur de tolérance que vous souhaitez.
Limites
Lettres courbes
Les segments de ligne ne sont pas idéaux: de nombreuses lettres sont courbes! Comment représentez-vous un «P» ou un «O»?
Vous pouvez utiliser de nombreux segments de ligne (peut-être avec une marge d'erreur plus importante).
Vous aussi pouvez commencer à utiliser des courbes de Bézier au lieu de lignes pour un plus en forme, mais notez que trouver le point le plus proche sur un Bézier est beaucoup plus que complexe plus a beaucoup d' autres opérations de mesure.
Inadéquations
Des marges de tolérance trop détendues pour la distance des lignes et la couverture de la lettre pourraient avoir des conséquences inattendues.
Par exemple, le joueur a peut-être essayé de dessiner un «H» ici.
Boucles et chevauchements
Les boucles ou les chevauchements dans le chemin tracé par le joueur peuvent entraîner le comptage double de certaines parties du dessin lors de leur projection sur le segment de ligne le plus proche.
Cela pourrait être contourné en effectuant un traitement plus sophistiqué sur les vecteurs projetés, peut-être en stockant exactement où le vecteur projeté serait (stockez également la direction de la projection et le point le plus proche sur le segment de ligne au point sur la ligne dessinée par le joueur) , puis en rejeter de nouveaux qui le chevauchent.
Si le joueur dessinait un seul chemin et que celui-ci était traité en commençant à la fin marquée par le cercle bleu, les parties vertes de ce chemin seraient acceptées et les rouges rejetées, car leur projection chevaucherait certaines parties traitées auparavant.
L'implémentation a de nombreuses subtilités techniques qui appartiendraient probablement à une question différente.
Joueurs imprévisiblement aventureux
Un joueur peut dessiner quelque chose de bizarre qui passe toujours .
Bien que vous puissiez appeler cela une fonctionnalité! :)