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
Classe du RayonCode: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; } }
Méthode mainCode: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); } }
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"); }
-----