Raytracing : Problème de calcul et d'affichage d'un plan
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Raytracing : Problème de calcul et d'affichage d'un plan



  1. #1
    invite4766dea5

    Raytracing : Problème de calcul et d'affichage d'un plan


    ------

    Bonsoir à tous,

    Je suis actuellement en train de coder un un logiciel de raytracing en c#,
    et il se trouve que j'ai un petit soucis avec le calcul et l'affichage d'un plan.

    En fait lors du calcul du plan, je me retrouve avec un plan en haut de mon image, alors
    que je souhaite qu'il soit en bas, et j'ai beau chercher je trouve pas pourquoi =[.

    Du coup ,j'ai regardé un peu partout sur le net pour trouver les principales caractéristiques d'un plan,
    et de ce que j'en ai compris il est définit par un Vecteur 3D N unitaire et une distance d,
    mais j'ai l'impression que soit j'applique mal la formule de calcul d'intersection, soit j'ai rien
    compris au calcul. Et comme je suis devenu une ouiche en math, j'ai trop du mal à comprendre,
    donc si une âme charitable pouvait m'aider ça serait gentil,

    Merci d'avance !

    Je met le code de la classe du Plan, du Rayon et la méthode main aussi :

    Classe du Plan
    Code:
        public class Plan : IGeoObject
        {
            /// <summary>
            /// Normal
            /// </summary>
            Vector3 normal;
    
            /// <summary>
            /// Matériau utilisé par le plan
            /// </summary>
            Material material;
    
            /// <summary>
            /// Distance du plan
            /// </summary>
            float planDist;
    
            /// <summary>
            /// Initialise une nouvelle instance d'un objet plan
            /// </summary>
            /// <param name="normal">Vecteur normal</param>
            /// <param name="planDist">distance du plan</param>
            /// <param name="material">matériau utilisé</param>
            public Plan(Vector3 normal, float planDist, Material material)
            {
                this.normal = new Vector3(normal.X, normal.Y, normal.Z);
                this.material = new Material(material.red, material.green, material.blue);
                this.planDist = planDist;
            }
    
    
            /// <summary>
            /// Méthode de calcule d'intersection entre le plan
            /// et le rayon
            /// </summary>
            /// <param name="ray">rayon</param>
            /// <param name="t">distance t</param>
            /// <returns>booléen pour savoir s'il y'a intersection ou non</returns>
            public bool Intersects(RTRay ray, ref float t)
            {
                //On calcule le produit scalaire
                float dotProdut = Vector3.Dot(this.normal, ray.dirVector);
    
                if (dotProdut > 0.0f)
                {
                    //on calcule la distance entre le rayon et le plant
                    float dist = -(Vector3.Dot(this.normal, ray.startPoint) + this.planDist) / dotProdut;
    
                    //si la distance est > 0.0f, il y'a intersection
                    if (dist > 0.0f)
                    {
                        if (dist < t)
                        {
                            //on remplace l'ancienne distance par celle calculée
                            t = dist;
                            return true;
                        }
                    }
                }
    
                return false;
            }
    
            /// <summary>
            /// Renvoi le matériau utilisé
            /// </summary>
            /// <returns>matériau utilisé</returns>
            public Material GetMaterial()
            {
                return this.material;
            }
        }
    Classe du Rayon
    Code:
        public class RTRay
        {
            /// <summary>
            /// Coordonnées du point de départ du rayon
            /// </summary>
            public Vector3 startPoint;
    
            /// <summary>
            /// Vecteur directeur du rayon
            /// </summary>
            public Vector3 dirVector;
    
            public RTRay(Vector3 startPoint, Vector3 dirVector)
            {
                this.startPoint = new Vector3(startPoint.X, startPoint.Y, startPoint.Z);
                this.dirVector = new Vector3(dirVector.X, dirVector.Y, dirVector.Z);
            }
        }
    Méthode main
    Code:
            static void Main(string[] args)
            {
                //Création de l'image
                Bitmap bmp = new Bitmap(1024, 768);
                
                //Création des matériaux
                Material mat = new Material(1.0f, 0.0f, 0.0f);
                Material mat1 = new Material(0.0f, 1.0f, 0.0f);
                Material mat2 = new Material(0.0f, 0.0f, 1.0f);
                Material mat3 = new Material(0.30f, 0.30f, 0.30f);
    
                //Création des Objets
                Vector3 spherePos = new Vector3(233.0f, 290.0f, 0.0f);
                Vector3 spherePos1 = new Vector3(430.0f, 420.0f, 0.0f);
                Vector3 spherePos2 = new Vector3(100.0f, 75.0f, 0.0f);
                Sphere sphere = new Sphere(spherePos, 75.0f, mat);
                Sphere sphere1 = new Sphere(spherePos1, 75.0f, mat1);
                Sphere sphere2 = new Sphere(spherePos2, 75.0f, mat2);
                Vector3 planPos = new Vector3(0, 700, 50);
                Plan plan = new Plan(planPos, 4.4f, mat3);
                
                //Ajout des objets dans la list
                List<IGeoObject> objectList = new List<IGeoObject>();
                objectList.Add(sphere);
                objectList.Add(sphere1);
                objectList.Add(sphere2);
                objectList.Add(plan);
    
                //Byte de couleur
                Byte red;
                Byte green;
                Byte blue;
    
                //Boucles de lancer de rayon
                for (int y = 0; y < bmp.Height; ++y)
                {
                    for (int x = 0; x < bmp.Width; ++x)
                    {
                        bool collide = false;
                        int currentObject = -1;
    
                        //Point de départ du rayon
                        Vector3 startPoint = new Vector3((float)x, (float)y, -2000.0f);
                        //Vecteur directeur du rayon
                        Vector3 dirVector = new Vector3(0.0f, 0.0f, 1.0f);
    
                        ///Création du rayon ayant pour point de départ startPoint
                        ///et pour vecteur directeur dirVector
                        RTRay viewRay = new RTRay(startPoint, dirVector);
    
                        ///distance t entre le point de départ du rayon
                        ///et le premier objet 'intersecté'
                        float t = 1000000.0f;
    
                        ///Pour chaque objet contenu dans la liste d'objet
                        ///on calcule le point d'intersection
                        for (int i = 0; i < objectList.Count(); ++i)
                        {
                            ///On calcule le point d'intersection entre
                            ///le rayon et l'objet en cours
                            collide = objectList[i].Intersects(viewRay, ref t);
    
                            ///s'il y'a collision l'objet est sélectionné
                            ///et on sort de la boucle
                            if (collide)
                            {
                                currentObject = i;
                                break;
                            }
                        }
    
                        //On affecte les couleurs en fonction de l'objet
                        if (currentObject == -1)
                        {
                            red = Convert.ToByte(0);
                            green = Convert.ToByte(0);
                            blue = Convert.ToByte(0);
                            bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(red, green, blue));
                        }
                        else
                        {
                            Material material = objectList[currentObject].GetMaterial();
                            red = Convert.ToByte(Math.Min(material.red * 255.0f, 255.0f));
                            green = Convert.ToByte(Math.Min(material.green * 255.0f, 255.0f));
                            blue = Convert.ToByte(Math.Min(material.blue * 255.0f, 255.0f));
                            bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(red, green, blue));
                        }
    
                        ///TO-DO : Ajouter les lumières
                    }
                }
    
                bmp.Save("result.bmp");
            }

    -----

  2. #2
    invite1d577638

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    Salut à toi,

    Pour avoir déjà codé un raytraceur en Vb, je peux peut être t'aider un peu.

    Un plan est effectivement défini par son vecteur normal et une distance, donc avec une équation du type :

    a*x + b*y +c*z +d = 0

    avec {a, b, c} ton vecteur normal et D la distance vis à vis de l'origine.

    J'ai pas regardé ton code en détails, mais pour afficher un plan tu as effectivement à rechercher l'intersection entre ce dernier et des rayons. (en gros résoudre l'équa proposée ci dessus avec l'équa de ta droite)

    Si tu as déjà un plan qui s'affiche, as-tu pensé à inverser la normale {-a, -b, -c} ? (change aussi D si besoin ?)

    Tiens moi au jus !

  3. #3
    invite4766dea5

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    Salut, merci de m'avoir répondu,

    J'ai testé de passer la normale en négative et la distance D aussi, le résultat est que le plan ne s'affiche plus,
    j'ai tenté aussi en utilisant une distance négative avec une normale positive et ça m'affiche toujours
    le plan au dessus.
    Donc je sais pas si c'est un problème qui est lié au coordonnées du plan, au coordonnées du rayon
    ou bien est-ce que je dois utiliser les translations/rotations dans le calcul des coordonées =/.

  4. #4
    invite1d577638

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    Hmmm.... Etrange en effet.

    Deux sources possibles d'erreur :
    -problème de repère, en gros si tu t'es fixé une normale positive qui est censée aller "vers le haut" alors ton plan est inversé -> regarde du coté de la génération des rayons. Un -1 doit manquer quelque part.

    -quand tu as inversé la normale, (et corrigé D si besoin) as tu pensé à modifier la position de ta source lumineuse (si tu en as une ?)

    Hésites pas aussi à ajouter une sphère comme primitive, c'est assez simple (pas + compliqué qu'un plan) et tu peux sortir de jolies choses.

    Quelques liens qui peuvent t'aider:
    http://raphaello.univ-fcomte.fr/ig/r...erderayons.htm
    http://www.alrj.org/docs/3D/raytrace...ertutchap1.htm

  5. A voir en vidéo sur Futura
  6. #5
    invite4766dea5

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    En ce qui concerne les sphères elles s'affichent correctement aux bonnes coordonnées.
    Je dois effectivement avoir un problème avec la normale de mon plan, je vais investiguer et m'aider
    des sites que tu m'as passé.

    En tout cas merci de m'avoir aidé !

  7. #6
    invite1d577638

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    De rien !

    Si c'est un problème de formule, les site que je t'ai indiqué peuvent t'aider, ou sinon cherche "intersection droite plan" dans google...

  8. #7
    invite4766dea5

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    En fait, je viens de trouver la solution à mon problème et je m'aperçois que je suis vraiment stupide en fait .
    J'ai réécris les formules que j'utilise, elles sont correctes, et j'ai commencé à jouer avec les valeurs de ma normal et de la distance,
    et en fait c'était juste un problème de.... Distance .

    Du coup quand j'ai fait les test que tu m'avais dit tout à l'heure sur la distance j'avais modifié, les valeurs de la normal,
    du coup j'ai pas fait attention et là en réécrivant les formules et en remettant les valeurs par défaut de la normal,
    j'ai juste changé la distance et c'est passé, vraiment, mais alors parfois la solution est tellement évidente que tu te dis
    ça peut pas être ça .

    En tout cas à nouveau un grand merci, car si j'avais pas relu tes postes je m'en serai pas sorti je pense .

  9. #8
    invite1d577638

    Re : Raytracing : Problème de calcul et d'affichage d'un plan

    Et bien tant mieux !

    Et bonne chance pour la suite... Quand tu vas attaquer la réflexion et autres difficultés, ça va se compliquer !

Discussions similaires

  1. Problème d'affichage d'un menu (rollover) avec IE6
    Par invited0300e0f dans le forum Internet - Réseau - Sécurité générale
    Réponses: 6
    Dernier message: 05/01/2010, 15h15
  2. Calcul d'equation de plan à partir d'un tétraedre
    Par invite40f82214 dans le forum Mathématiques du collège et du lycée
    Réponses: 1
    Dernier message: 30/09/2009, 00h42
  3. convertir coordonée d'un point d'un plan dans un autre plan
    Par invitec6a67b2e dans le forum Mathématiques du supérieur
    Réponses: 1
    Dernier message: 26/09/2007, 20h10
  4. probleme d'affichage LCD d'un poste radio AKAI
    Par invite823c07fa dans le forum Dépannage
    Réponses: 6
    Dernier message: 21/06/2006, 14h50
  5. probleme d'affichage LCD d'un auto-radio PIONEER
    Par invitef8ea2e84 dans le forum Dépannage
    Réponses: 6
    Dernier message: 12/06/2006, 15h09