public override Vector normal(XYZPoint p) { Vector v1 = new Vector(points[0], points[1]); Vector v2 = new Vector(points[0], points[2]); return(v1[v2]); }
public static Polyhedron CreateHexahedron(XYZPoint a, XYZPoint b, XYZPoint q) { XYZPoint[] cd = GetVertecesForSquare(a, b, q); XYZPoint c = cd[0]; XYZPoint d = cd[1]; Vector m = new Vector(a, b); Vector n = new Vector(a, c); double sideLen = m.Norm(); Vector h = m[n].Normalize() * sideLen; XYZPoint a1 = new XYZPoint(a.X + h.X, a.Y + h.Y, a.Z + h.Z); XYZPoint b1 = new XYZPoint(b.X + h.X, b.Y + h.Y, b.Z + h.Z); XYZPoint c1 = new XYZPoint(c.X + h.X, c.Y + h.Y, c.Z + h.Z); XYZPoint d1 = new XYZPoint(d.X + h.X, d.Y + h.Y, d.Z + h.Z); Polyhedron Hexahedron = new Polyhedron(); Hexahedron.verges = new Verge[6]; Hexahedron.verges[0] = Verge.CreateSquare(a, b, c, d); Hexahedron.verges[1] = Verge.CreateSquare(a, b, b1, a1); Hexahedron.verges[2] = Verge.CreateSquare(b, c, c1, b1); Hexahedron.verges[3] = Verge.CreateSquare(c, d, d1, c1); Hexahedron.verges[4] = Verge.CreateSquare(a, d, d1, a1); Hexahedron.verges[5] = Verge.CreateSquare(a1, b1, c1, d1); double cx = (a.X + c1.X) / 2; double cy = (a.Y + c1.Y) / 2; double cz = (a.Z + c1.Z) / 2; Hexahedron.center = new XYZPoint(cx, cy, cz); return(Hexahedron); }
private List <XYZPoint> find_rays() { var corners = make_grid_corners(pictureBox1.Width * Math.Sqrt(3) / 2); // было 100 List <XYZPoint> points = new List <XYZPoint>(); var w = pictureBox1.Width; var h = pictureBox1.Height; var step_h_x = (corners[2].X - corners[0].X) / h; var step_h_y = (corners[2].Y - corners[0].Y) / h; var step_h_z = (corners[2].Z - corners[0].Z) / h; var step_w_x = (corners[1].X - corners[0].X) / w; var step_w_y = (corners[1].Y - corners[0].Y) / w; var step_w_z = (corners[1].Z - corners[0].Z) / w; for (int i = 0; i < h; ++i) { var p = new XYZPoint( corners[0].X + step_h_x * i, corners[0].Y + step_h_y * i, corners[0].Z + step_h_z * i); for (int j = 0; j < w; ++j) { points.Add(new XYZPoint( p.X + step_w_x * j, p.Y + step_w_y * j, p.Z + step_w_z * j)); } } return(points); }
public XYZPoint[] GetPoints() { XYZPoint[] res = new XYZPoint[edges.Length]; for (int i = 0; i < res.Length; ++i) { res[i] = edges[i].First; } return(res); }
private double triangle_square(XYZPoint A, XYZPoint B, XYZPoint C) { double a = new Vector(B, C).Norm(); double b = new Vector(A, C).Norm(); double c = new Vector(A, B).Norm(); double p = (a + b + c) / 2; return(Math.Sqrt(p * (p - a) * (p - b) * (p - c))); }
public Polyhedron(Verge[] _verges, XYZPoint _center) { verges = new Verge[_verges.Length]; for (int i = 0; i < verges.Length; ++i) { verges[i] = _verges[i].Clone() as Verge; } center = _center.Clone() as XYZPoint; }
public static Verge CreateSquare(XYZPoint a, XYZPoint b, XYZPoint c, XYZPoint d) { Verge Square = new Verge(); Square.edges = new Edge[4]; Square.edges[0] = new Edge(a, b); Square.edges[1] = new Edge(b, c); Square.edges[2] = new Edge(c, d); Square.edges[3] = new Edge(d, a); return(Square); }
public Wall(XYZPoint p1, XYZPoint p2, XYZPoint p3, XYZPoint p4) { Vector v1 = new Vector(p1, p2); Vector v2 = new Vector(p1, p3); Vector n = v1[v2]; double d = -(n.X * p1.X + n.Y * p1.Y + n.Z * p1.Z); points = new XYZPoint[4]; points[0] = p1; points[1] = p2; points[2] = p3; points[3] = p4; square = triangle_square(p1, p2, p3) + triangle_square(p1, p3, p4); }
public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t) { Vector d = new Vector( ray_pos.X - Camera_pos.X, ray_pos.Y - Camera_pos.Y, ray_pos.Z - Camera_pos.Z); Vector c = new Vector( Camera_pos.X - this.C.X, Camera_pos.Y - this.C.Y, Camera_pos.Z - this.C.Z); double k1 = d * d, k2 = 2 * (c * d), k3 = (c * c) - this.R * this.R; double D = k2 * k2 - 4 * k1 * k3; if (D < 0) { return(false); } double x1 = (-k2 + Math.Sqrt(D)) / (2 * k1); double x2 = (-k2 - Math.Sqrt(D)) / (2 * k1); double x = 0; if (x1 < eps && x2 < eps) { return(false); } else if (x1 < eps) { x = x2; } else if (x2 < eps) { x = x1; } else { x = x1 < x2 ? x1 : x2; } t = new XYZPoint( Camera_pos.X + d.X * x, Camera_pos.Y + d.Y * x, Camera_pos.Z + d.Z * x); return(true); }
private static XYZPoint[] GetVertecesForSquare(XYZPoint a, XYZPoint b, XYZPoint q) { Vector m = new Vector(a, b); Vector n = new Vector(a, q); double sideLen = m.Norm(); double coeff = (m * n) / (m * m); Vector h = (n - (coeff * m)).Normalize() * sideLen; Vector r = m + h; XYZPoint c = new XYZPoint(a.X + r.X, a.Y + r.Y, a.Z + r.Z); XYZPoint d = new XYZPoint(a.X + h.X, a.Y + h.Y, a.Z + h.Z); return(new XYZPoint[2] { c, d }); }
private void DrawButton_Click(Object sender, EventArgs e) { Init(); var points = find_rays(); var Camera_pos = new XYZPoint(2, 11, 2); g.Clear(ambient); for (int i = 0; i < pictureBox1.Height; i += 1) { for (int j = 0; j < pictureBox1.Width; j += 1) { var clr = ray_step(Camera_pos, points[i * pictureBox1.Width + j], 1); g.FillRectangle(new SolidBrush(clr), j, i, 1, 1); } } }
private List <XYZPoint> make_grid_corners(double dist) { var w = pictureBox1.Width / 2; var h = pictureBox1.Height / 2; Camera Camera = CreateCamera(); Vector view = Camera.View * dist; XYZPoint m0 = new XYZPoint( Camera.Pos.X + view.X, Camera.Pos.Y + view.Y, Camera.Pos.Z + view.Z); Vector hor = Camera.Hor * w; Vector vert = Camera.Vert * h; XYZPoint p1 = new XYZPoint( m0.X - hor.X - vert.X, m0.Y - hor.Y - vert.Y, m0.Z - hor.Z - vert.Z); XYZPoint p2 = new XYZPoint( m0.X + hor.X - vert.X, m0.Y + hor.Y - vert.Y, m0.Z + hor.Z - vert.Z); XYZPoint p3 = new XYZPoint( m0.X - hor.X + vert.X, m0.Y - hor.Y + vert.Y, m0.Z - hor.Z + vert.Z); XYZPoint p4 = new XYZPoint( m0.X + hor.X + vert.X, m0.Y + hor.Y + vert.Y, m0.Z + hor.Z + vert.Z); List <XYZPoint> res = new List <XYZPoint>(); res.Add(p1); res.Add(p2); res.Add(p3); res.Add(p4); return(res); }
public Sphere(Polyhedron ph) { var p = ph.Verges[0].Edges[0].First; var dist = new Vector(ph.Center, p).Norm(); foreach (var f in ph.Verges) { foreach (var e in f.Edges) { var pp = e.First; var ddist = new Vector(ph.Center, pp).Norm(); if (ddist > dist) { dist = ddist; p = pp; } } } this.center = ph.Center; this.radius = dist; }
public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t) { Vector n = this.normal(null); double d = -(n.X * points[0].X + n.Y * points[0].Y + n.Z * points[0].Z); Vector v = new Vector(Camera_pos, ray_pos); Vector u = new Vector(Camera_pos); double denum = n * v; if (Math.Abs(denum) < eps) { return(false); } double num = n * u + d; double tp = -num / denum; if (tp < eps) { return(false); } t = new XYZPoint( v.X * tp + u.X, v.Y * tp + u.Y, v.Z * tp + u.Z); double square = 0; for (int i = 0; i < 4; ++i) { square += triangle_square(points[i], points[(i + 1) % 4], t); } if (Math.Abs(this.square - square) > eps) { return(false); } return(true); }
public override Vector normal(XYZPoint p) { foreach (var face in ph.Verges) { double square = 0; int cnt = face.Edges.Count(); for (int i = 0; i < cnt; ++i) { square += triangle_square(face.Edges[i].First, face.Edges[(i + 1) % cnt].First, p); } if (Math.Abs(squares[face] - square) > eps) { continue; } var p1 = face.Edges[0].First; var p2 = face.Edges[1].First; var p3 = face.Edges[2].First; Vector v1 = new Vector(p1, p2); Vector v2 = new Vector(p1, p3); return(v1[v2]); } return(new Vector()); }
public Edge(XYZPoint a, XYZPoint b) { this.a = new XYZPoint(a); this.b = new XYZPoint(b); }
public Sphere(XYZPoint c, double r) { this.center = c; this.radius = r; }
virtual public bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t) { return(true); }
public XYZPoint(XYZPoint a) { x = a.x; y = a.y; z = a.z; }
public void Copy(XYZPoint a) { x = a.x; y = a.y; z = a.z; }
private Color ray_step(XYZPoint start, XYZPoint p, double intense) { if (intense < 0.01) { return(Color.Black); } double dist = double.MaxValue; Model obj = null; XYZPoint cross = new XYZPoint(); foreach (var o in Models) { XYZPoint t = new XYZPoint(); if (o.find_cross(start, p, ref t)) { double d1 = new Vector(start, t).Norm(); if (d1 < dist) { dist = d1; obj = o; cross = t; } } } if (obj == null) { return(ambient); } // диффузное освещение double ldiff = 0; XYZPoint tt = new XYZPoint(); foreach (var l in lights) { bool flag = false; double trans_coeff = 1; foreach (var o in Models) { if (o.find_cross(cross, l, ref tt) && new Vector(tt, cross).Norm() < new Vector(l, cross).Norm()) { if (trans[o] > 0) { trans_coeff *= trans[o]; } else { flag = true; break; } } } if (flag) { continue; } double kd = diffuse[obj]; double l0 = lights_power[l]; Vector N = obj.normal(cross); Vector L = new Vector(cross, l); if (N * L < 0) { N = -N; } double cos = (N * L) / N.Norm() / L.Norm(); ldiff += kd * cos * l0 * trans_coeff; } Color clr_diff = light_color(colors[obj], (ldiff + amb_light) * intense); // отражение Color clr_refl = Color.Black; if (reflect[obj] > 0) { Vector l = new Vector(start, p); l = l.Normalize(); Vector n = obj.normal(cross); n = n.Normalize(); if (n * l > 0) { n = -n; } Vector r = l - 2 * n * (n * l); XYZPoint p_new = new XYZPoint( cross.X + r.X, cross.Y + r.Y, cross.Z + r.Z); clr_refl = ray_step(cross, p_new, intense * reflect[obj]); } //преломление Color clr_trans = Color.Black; if (trans[obj] > 0) { Vector l = new Vector(start, p); l = l.Normalize(); Vector n = obj.normal(cross); n = n.Normalize(); if (n * l > 0) { n = -n; } double coef = 1 / refract[obj]; double cos = Math.Sqrt(1 - coef * coef * (1 - (n * l) * (n * l))); Vector t = coef * l - (cos + coef * (n * l)) * n; XYZPoint p_new = new XYZPoint( cross.X + t.X, cross.Y + t.Y, cross.Z + t.Z); for (int i = 0; i < 10; ++i) { if (!obj.find_cross(cross, p_new, ref tt)) { return(clr_diff); } l = new Vector(cross, p_new); l = l.Normalize(); n = obj.normal(tt); n.Normalize(); if (n * l > 0) { n = -n; } coef = refract[obj]; cos = 1 - coef * coef * (1 - (n * l) * (n * l)); if (cos < 0) { if (i == 9) { cross = tt; p_new = new XYZPoint( cross.X + l.X, cross.Y + l.Y, cross.Z + l.Z); break; } Vector r = l - 2 * n * (n * l); cross = tt; p_new = new XYZPoint( cross.X + r.X, cross.Y + r.Y, cross.Z + r.Z); continue; } cos = Math.Sqrt(cos); t = coef * l - (cos + coef * (n * l)) * n; p_new = new XYZPoint( tt.X + t.X, tt.Y + t.Y, tt.Z + t.Z); break; } clr_trans = ray_step(tt, p_new, intense * trans[obj]); } return(add_colors(clr_diff, clr_refl, clr_trans, reflect[obj] > 0, trans[obj] > 0)); }
public override Vector normal(XYZPoint p) { return(new Vector(this.C, p)); }
public Vector(XYZPoint a, XYZPoint b) { this.x = b.X - a.X; this.y = b.Y - a.Y; this.z = b.Z - a.Z; }
public Vector(XYZPoint a) { this.x = a.X; this.y = a.Y; this.z = a.Z; }
public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t) { if (!outside_sphere.find_cross(Camera_pos, ray_pos, ref t)) { return(false); } double dist = double.MaxValue; XYZPoint res = new XYZPoint(); bool flag = false; foreach (var face in ph.Verges) { var p1 = face.Edges[0].First; var p2 = face.Edges[1].First; var p3 = face.Edges[2].First; Vector v1 = new Vector(p1, p2); Vector v2 = new Vector(p1, p3); Vector n = v1[v2]; double d = -(n.X * p1.X + n.Y * p1.Y + n.Z * p1.Z); Vector v = new Vector(Camera_pos, ray_pos); Vector u = new Vector(Camera_pos); double denum = n * v; if (Math.Abs(denum) < eps) { continue; } double num = n * u + d; double tp = -num / denum; if (tp < eps) { continue; } t = new XYZPoint( v.X * tp + u.X, v.Y * tp + u.Y, v.Z * tp + u.Z); double square = 0; int cnt = face.Edges.Count(); for (int i = 0; i < cnt; ++i) { square += triangle_square(face.Edges[i].First, face.Edges[(i + 1) % cnt].First, t); } if (Math.Abs(squares[face] - square) > eps) { continue; } var dist_t = new Vector(Camera_pos, t).Norm(); if (dist_t < dist) { res = t.Clone() as XYZPoint; dist = dist_t; flag = true; } } t = res.Clone() as XYZPoint; return(flag); }
virtual public Vector normal(XYZPoint p) { return(new Vector()); }