web-dev-qa-db-fra.com

Comment faire une intersection de plan de rayon?

Comment calculer l'intersection entre un rayon et un plan? J'ai visité tous les sites Web possibles que je peux trouver et voici ce que j'ai accompli jusqu'à présent:

float denom = normal.dot(ray.direction);

if (denom > 0)
{
    float t = -((center - ray.Origin).dot(normal)) / denom;

    if (t >= 0)
    {
        rec.tHit = t;
        rec.anyHit = true;
        computeSurfaceHitFields(ray, rec);
        return true;
    }
}

Cela ne fonctionne pas: s
La saisie de ma fonction est:
rayon: qui contient l'origine et la direction.
rec: une classe de conteneur pour stocker les informations de hit (bool, t, etc.)

Ma fonction a accès à l'avion:
point: le point qui définit le plan
normal: la normale qui définit le plan

9
Pontus Magnusson

Comme vous l'avez fait remarquer, vous souhaitez également autoriser le dénominateur à être négatif, sinon vous manquerez d'intersections avec la face avant de votre avion. Cependant, vous voulez toujours un test pour éviter une division par zéro, ce qui indiquerait que le rayon est parallèle au plan. Vous avez également une négation superflue dans votre calcul de t. Globalement, cela devrait ressembler à ceci:

float denom = normal.dot(ray.direction);
if (abs(denom) > 0.0001f) // your favorite epsilon
{
    float t = (center - ray.Origin).dot(normal) / denom;
    if (t >= 0) return true; // you might want to allow an epsilon here too
}
return false;
15
Trillian

Considérons d’abord le calcul de l’intersection plan-rayon:

En général, on coupe la forme paramétrique du rayon, avec la forme implicite de la géométrie.

Donc, étant donné un rayon de la forme x = a * t + a0, y = b * t + b0, z = c * t + c0;

et un plan de la forme: A * * B * * C z + D = 0;

substituez maintenant les équations des rayons x, y et z dans l'équation du plan et vous obtiendrez un polynôme en t. vous résolvez ensuite ce polynôme pour les valeurs réelles de t. Avec ces valeurs de t, vous pouvez remplacer l’équation du rayon pour obtenir les valeurs réelles de x, y et z. Voici en Maxima:

enter image description here

Notez que la réponse ressemble au quotient de deux produits scalaires! La normale à un plan correspond aux trois premiers coefficients de l'équation dans le plan A, B et C. Vous avez encore besoin de D uniquement déterminer le plan. Ensuite, vous le codez dans la langue de votre choix, comme suit:

Point3D intersectRayPlane(Ray ray, Plane plane)
{
    Point3D point3D;

    //  Do the dot products and find t > epsilon that provides intersection.


    return (point3D);
}
6
vwvan

implémentation de la réponse de vwvan

Vector3 Intersect(Vector3 planeP, Vector3 planeN, Vector3 rayP, Vector3 rayD)
{
    var d = Vector3.Dot(planeP, -planeN);
    var t = -(d + rayP.z * planeN.z + rayP.y * planeN.y + rayP.x * planeN.x) / (rayD.z * planeN.z + rayD.y * planeN.y + rayD.x * planeN.x);
    return rayP + t * rayD;
}
1
Bas Smit