public void LineRotateRad(float rang, PointXYZ p1, PointXYZ p2) { p2 = new PointXYZ(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); p2 = PointXYZ.normal(p2); float[,] mt = GetMatrix(); ApplyMatrix(RotateAroundLine(mt, p1, p2, rang)); }
//модель освещения public PointXYZ Lumiance(PointXYZ hit_point, PointXYZ normal, PointXYZ material_color, float diffuse_coef) { PointXYZ direction = PointXYZ.normal(point_light - hit_point);// направление луча //если угол между нормалью и направлением луча больше 90 градусов,то диффузное освещение равно 0 PointXYZ diff = diffuse_coef * color_light * Math.Max(PointXYZ.ScalarMul(normal, direction), 0); return(new PointXYZ(diff.X * material_color.X, diff.Y * material_color.Y, diff.Z * material_color.Z)); }
public static PointXYZ GetNormal(Polygon S) { if (S.points.Count() < 3) { return(new PointXYZ(0, 0, 0)); } PointXYZ U = S.GetPoint(1) - S.GetPoint(0); PointXYZ V = S.GetPoint(S.points.Count - 1) - S.GetPoint(0); PointXYZ normal = U * V; return(PointXYZ.normal(normal)); }
//преломление //все вычисления взяты из презентации public Ray Refract(PointXYZ hit_point, PointXYZ normal, float refraction, float refract_coef) { Ray res_ray = new Ray(); float sclr = PointXYZ.ScalarMul(normal, End); /* * Если луч падает,то он проходит прямо,не преломляясь */ float n1n2div = refraction / refract_coef; float theta_formula = 1 - n1n2div * n1n2div * (1 - sclr * sclr); if (theta_formula >= 0) { float cos_theta = (float)Math.Sqrt(theta_formula); res_ray.Start = new PointXYZ(hit_point); res_ray.End = PointXYZ.normal(End * n1n2div - (cos_theta + n1n2div * sclr) * normal); return(res_ray); } else { return(null); } }
private void button1_Click(object sender, EventArgs e) { Figure room = MakeRoom(); cameraPoint = MakeCamera(room.Polygons[0]); figuresList.Add(room); raySource = new Lamp(new PointXYZ(0f, 2f, 4.9f), new PointXYZ(1f, 1f, 1f)); AddBigCube(); AddLittleCube(); /* * Учитывая разницу между размером комнаты и экранным отображение приводим координаты к пикселям */ pixels = new PointXYZ[w, h]; pixels_color = new Color[w, h]; PointXYZ step_up = (ur - ul) / (w - 1); //отношение ширины комнаты к ширине экрана PointXYZ step_down = (dr - dl) / (w - 1); //отношение высоты комнаты к высоте экрана PointXYZ up = new PointXYZ(ul); PointXYZ down = new PointXYZ(dl); for (int i = 0; i < w; ++i) { PointXYZ step_y = (up - down) / (h - 1); PointXYZ d = new PointXYZ(down); for (int j = 0; j < h; ++j) { pixels[i, j] = d; d += step_y; } up += step_up; down += step_down; } /* * Количество первичных лучей также известно – это общее * количество пикселей видового окна */ for (int i = 0; i < w; ++i) { for (int j = 0; j < h; ++j) { Ray r = new Ray(cameraPoint, pixels[i, j]); r.Start = new PointXYZ(pixels[i, j]); PointXYZ color = RTAlgotithm(r, 10, 1);//луч,кол-во итераций,коэфф if (color.X > 1.0f || color.Y > 1.0f || color.Z > 1.0f) { color = PointXYZ.normal(color); } pixels_color[i, j] = Color.FromArgb((int)(255 * color.X), (int)(255 * color.Y), (int)(255 * color.Z)); } } for (int i = 0; i < w; ++i) { for (int j = 0; j < h; ++j) { (pictureBox1.Image as Bitmap).SetPixel(i, j, pixels_color[i, j]); } pictureBox1.Invalidate(); } }
public Ray(PointXYZ st, PointXYZ end) { Start = new PointXYZ(st); End = PointXYZ.normal(end - st); }