2010-12-14 105 views
4

J'ai écrit une méthode simple d'assistant qui calcule la distance d'un point à un plan. Cependant, il semble retourner des résultats absurdes. Le code que j'ai pour créer un avion est donc:Distance à un avion

Plane = new Plane(vertices.First().Position, vertices.Skip(1).First().Position, vertices.Skip(2).First().Position); 

Assez simple, j'espère que vous serez d'accord. Il crée une structure plane XNA en utilisant trois points.

Maintenant, immédiatement après ce que je fais:

foreach (var v in vertices) 
{ 
    float d = Math.Abs(v.ComputeDistance(Plane)); 
    if (d > Constants.TOLERANCE) 
     throw new ArgumentException("all points in a polygon must share a common plane"); 
} 

En utilisant le même ensemble de sommets que je construisais le plan, je reçois cette exception jeté! Mathématiquement c'est impossible, puisque ces trois points doivent se trouver sur le plan.

méthode Mon ComputeDistance est:

public static float ComputeDistance(this Vector3 point, Plane plane) 
{ 
    float dot = Vector3.Dot(plane.Normal, point); 
    float value = dot - plane.D; 
    return value; 
} 

AsI comprendre, cela est exact. Alors, que pourrais-je faire de mal? Ou pourrais-je rencontrer un bug dans l'implémentation de XNA?

Quelques exemples de données:

Points: 
{X:0 Y:-0.5000001 Z:0.8660254} 
{X:0.75 Y:-0.5000001 Z:-0.4330128} 
{X:-0.75 Y:-0.5000001 Z:-0.4330126} 

Plane created: 
{Normal:{X:0 Y:0.9999999 Z:0} D:0.5} //I believe D should equal -0.5? 

Distance from point 1 to plane: 
1.0 
+0

Quelle est la valeur de 'Constants.TOLERANCE'? – DGH

+0

TOLERANCE = 1e-5f – Martin

+0

Cependant, la tolérance n'est pas le problème. Comme vous pouvez le voir à partir des nouveaux exemples de données que je viens d'éditer dans la distance est relativement vaste. – Martin

Répondre

6

Il semble que votre Plane soit implémenté pour que D ne soit pas la projection d'un de vos points sur le plan normal, mais plutôt le négatif de ceci. Vous pouvez penser à cela comme projetant un vecteur de l'avion à l'origine sur la normale.

Dans tous les cas, je crois que le changement

float value = dot - plane.D; 

à

float value = dot + plane.D; 

devrait arranger les choses. HTH.

+1

Mon Dieu, c'est tellement évident une fois que vous le dites! Merci beaucoup. – Martin

1

Ok, je ne suis pas tout à fait sûr que je comprends les mathématiques ici, mais je soupçonne (basé sur les formules de http://mathworld.wolfram.com/Point-PlaneDistance.html entre autres) que

float value = dot - plane.D; 

devrait effectivement être

float value = dot/plane.D; 

EDIT: Ok, comme mentionné dans les commentaires ci-dessous, cela n'a pas fonctionné. Ma meilleure suggestion est alors d'aller voir le lien ou google "distance entre un point et un avion" et essayer d'implémenter la formule d'une manière différente.

+0

Je travaillais à partir de cette réponse ici qui exprime en termes assez simples: http://social.msdn.microsoft.com/Forums/en/xnaframework/thread/226600b4-0de4-4bac-bc55-a4d9b84dd92f – Martin

+0

@Martin: Ok , il semble que vous suiviez cette suggestion correctement. Cependant, cette formule ne correspond à aucun des trois ou quatre autres sites que j'ai vu expliquer ce calcul. Pourriez-vous essayer mon idée, juste pour humourer moi? – DGH

+0

Bien sûr, pourquoi pas :) – Martin