2009-07-28 6 views
1

Autrement connu sous le nom d'arête vive, il s'agit d'une ligne que la souris ne peut pas traverser. Utile dans les jeux et autres.Implémentation d'un bord de délimitation de la souris

Actuellement, j'ai une fonction qui retourne si mon curseur de la souris est dans un polygone dessiné sur l'écran. Si ce n'est pas le cas, je déplace mon curseur sur le dernier point stocké dans le polygone.

if (!PointInPolygon(local, polyGon)) 
    { 
     Cursor.Position = safePoint; 
    } 
    else 
    { 
     safePoint = Cursor.Position; 
    } 

Je n'aime pas cela pour plusieurs raisons:

  • En raison de ralentir les temps de mise à jour ou pour une raison quelconque, je suis parfois en mesure de sortir de la boîte. Cela stocke alors cette position en tant que safePoint, en dehors du polygone. Ma souris est alors coincée dans cette position.

  • Les bords inclinés doivent former une croûte dans le sens de la pente. En poussant la souris à droite, un mur en forme de "/" devrait se terminer par le curseur dans le coin supérieur droit. Mais en raison de la nature de cette approche, aller au-dessus de la ligne va réinitialiser le curseur à l'endroit où il était auparavant. Continuer à pousser à droite ne fera que reprendre le curseur et ne le poussera pas "vers le haut de la pente".

Existe-t-il d'autres approches pour résoudre ce problème? Je suis surtout préoccupé par le dernier numéro: ce comportement transversal de pente est l'objectif principal de mon programme et je dois le faire fonctionner. Même si j'utilise cette méthode de base, des idées pour une optimisation de ce comportement spécifique?


EDIT:

Il a été suggéré par Reed que je retourne à la place au point que se rapproche le plus courant hors limites points. Étant donné les 4 coins d'un quadrilatère, comment trouver le point le plus proche dans/sur la forme?

Répondre

0
  1. trouver l'équation de la ligne de bord en utilisant les deux points d'extrémité.
  2. - (1/pente) donne la pente de la droite perpendiculaire.
  3. Résoudre l'équation linéaire de la ligne perpendiculaire en utilisant le point connu sur le bord (emplacement de la vraie souris)
  4. Résoudre l'intersection de la ligne de contour et de la ligne perpendiculaire.
  5. Placez le faux curseur à cet emplacement.
2

Au lieu de suivre un « SafePoint », je ferais ce qui suit:

Si vous trouvez votre extérieur de votre polygone, au lieu de revenir à un dernier point sûr connu, mettez la souris au point le plus proche/dans le polygone à l'emplacement de la souris actuelle. Cela contribuera également à la sensation, puisque le curseur aura tendance à suivre (lentement) les pentes sur le bord des polygones, etc.

Cela élimine également la nécessité de sauvegarder l'état entre les appels (safepoint).

+0

Hmm, bonne idée. Maintenant, j'ai juste besoin de comprendre, étant donné les 4 points qui délimitent le quadrilatère, quel serait le meilleur moyen de trouver le point le plus proche? – cksubs

+0

Voici quelques algorithmes pour vous: http://www.devmaster.net/forums/archive/index.php/t-103.html Avec de petits polygones (dépend de votre situation, mais généralement moins de 10 segments ou plus), juste force brute recherche point-> segments est souvent l'approche la plus rapide. –

-1

point le plus proche:

if(mouse.x > maxX) 
    mouse.x = maxX; 
else if(mouse.x < minX) 
    mouse.x = minX; 

// same for Y. 
+0

C'est une limite de polygone, pas un rectangle -1 –

+0

lol, me sert bien pour ne pas regarder le mot en haut :) – Eugene

+1

Eh bien, alors laissez tomber normal de chaque côté, et trouver plus courte distanse entre le point et l'intersection de la normale et le côté . – Eugene

2

Comment contraindre le point P l'intérieur d'un convexe polygone (non-convexe est un peu plus difficile) dans du 2-D (en supposant que l'ordre d'enroulement dans le sens horaire):

Pour chaque arête (Pi, Pj) du polygone ...

Trouver le vecteur normal N du bord (vecteur unitaire pointant de Pi à Pj, tournée de 90 degrés)

Trouver le déplacement D du bord au point P le long N (D = (P - Pi) dot N)

Si D est positif (ou négatif pour une commande d'enroulement anti-horaire), puis P = P - N * D

boucle de fin :)