//Przyblizenie według osi z private void TranslatedZ(trójkąt y, trójkąt x) { for (int i = 0; i < 3; i++) { y.tlist[i].Z = x.tlist[i].Z + 5.0f; } }
//cieniowanie i malowanie fugur za pomocą algorytma malarskiego public void FillFigure(trójkąt trójkąt, Bitmap bm) { float m = trójkąt.m; float R = m * 255; float G = m * 255; float B = m * 255; if (R < 0) { R = 0; } if (G < 0) { G = 0; } if (B < 0) { B = 0; } SolidBrush solidBrush = new SolidBrush(Color.FromArgb((int)R, (int)G, (int)B)); Point point1 = new Point((int)trójkąt.tlist[0].X, (int)trójkąt.tlist[0].Y); Point point2 = new Point((int)trójkąt.tlist[1].X, (int)trójkąt.tlist[1].Y); Point point3 = new Point((int)trójkąt.tlist[2].X, (int)trójkąt.tlist[2].Y); Point[] Points = { point1, point2, point3 }; using (var graphics = Graphics.FromImage(bm)) { graphics.FillPolygon(solidBrush, Points); } }
//skalowanie x i y private void Scale(trójkąt x) { for (int i = 0; i < 3; i++) { x.tlist[i].X += 2.0f; x.tlist[i].Y += 2.0f; x.tlist[i].X *= 0.3f * (float)pb.Width; x.tlist[i].Y *= 0.3f * (float)pb.Height; } }
//projekcja trójkąta private void MatrixMnożenia(Matrix4x4 matrixProj, trójkąt x, trójkąt y) { for (int i = 0; i < 3; i++) { y.tlist[i].X = x.tlist[i].X * matrixProj.M11 + x.tlist[i].Y * matrixProj.M21 + x.tlist[i].Z * matrixProj.M31 + matrixProj.M41; y.tlist[i].Y = x.tlist[i].X * matrixProj.M12 + x.tlist[i].Y * matrixProj.M22 + x.tlist[i].Z * matrixProj.M32 + matrixProj.M42; y.tlist[i].Z = x.tlist[i].X * matrixProj.M13 + x.tlist[i].Y * matrixProj.M23 + x.tlist[i].Z * matrixProj.M33 + matrixProj.M43; float w = x.tlist[i].X * matrixProj.M14 + x.tlist[i].Y * matrixProj.M24 + x.tlist[i].Z * matrixProj.M34 + matrixProj.M44; if (w != 0.0f) { y.tlist[i].X /= w; y.tlist[i].Y /= w; y.tlist[i].Z /= w; } } }
public void LoadFigure() { string[] lines = File.ReadAllLines(path); foreach (var line in lines) { if (line[0] == 'v' && line[1] == ' ') { string[] vertex = line.ToString().Split(' '); Vector3 v = new Vector3(float.Parse(vertex[1], CultureInfo.InvariantCulture.NumberFormat), float.Parse(vertex[2], CultureInfo.InvariantCulture.NumberFormat), float.Parse(vertex[3], CultureInfo.InvariantCulture.NumberFormat)); verticies.Add(v); } if (line[0] == 'f' && line[1] == ' ') { string[] points = line.Split(' '); int tri1, tri2, tri3; tri1 = int.Parse(points[1]) - 1; tri2 = int.Parse(points[2]) - 1; tri3 = int.Parse(points[3]) - 1; int[] tempIDTriangle = { tri1, tri2, tri3 }; indexOfVerticies.Add(tempIDTriangle); } } foreach (var singleTriangleIndex in indexOfVerticies) { int v1Index = singleTriangleIndex[0]; int v2Index = singleTriangleIndex[1]; int v3Index = singleTriangleIndex[2]; trójkąt tr = new trójkąt(new Vector4(verticies[v1Index], 0f), new Vector4(verticies[v2Index], 0f), new Vector4(verticies[v3Index], 0f)); Figures.Add(tr); } }
public void UserUpdate(TimeSpan time) { bm = new Bitmap(pb.Width, pb.Height); double Etime = time.TotalMilliseconds / 1000; Theta += 0.5f * (float)Etime; //obracanie sciany if ((Keyboard.GetKeyStates(Key.Down) & KeyStates.Down) > 0) { Camera.Y += 0.01f + (float)Etime; } if ((Keyboard.GetKeyStates(Key.Up) & KeyStates.Down) > 0) { Camera.Y -= 0.01f + (float)Etime; } if ((Keyboard.GetKeyStates(Key.Right) & KeyStates.Down) > 0) { Camera.X += 0.01f + (float)Etime; } if ((Keyboard.GetKeyStates(Key.Left) & KeyStates.Down) > 0) { Camera.X -= 0.01f + (float)Etime; } Vector4 Moving = Look * (8.0f * (float)Etime); //obracanie kamery if ((Keyboard.GetKeyStates(Key.W) & KeyStates.Down) > 0) { Camera = functions.addVector(Camera, Moving); } if ((Keyboard.GetKeyStates(Key.S) & KeyStates.Down) > 0) { Camera = functions.subVector(Camera, Moving); } if ((Keyboard.GetKeyStates(Key.A) & KeyStates.Down) > 0) { fPlayer += 0.05f + (float)Etime; } if ((Keyboard.GetKeyStates(Key.D) & KeyStates.Down) > 0) { fPlayer -= 0.05f + (float)Etime; } MRotX = functions.MRotateX(Theta); MRotZ = functions.MRotateZ(Theta); //camera Vector4 Up = new Vector4(0, 1, 0, 1); Vector4 Target = new Vector4(0, 0, 1, 1); Matrix4x4 CameraR = functions.MRotateY(fPlayer); Look = functions.MMultVector(Target, CameraR); Target = functions.addVector(Camera, Look); Matrix4x4 mCamera = functions.MPointAt(Camera, Target, Up); Matrix4x4 mView = functions.M_QuickInverse(mCamera); List <trójkąt> Rastr = new List <trójkąt>(); //rysowanie trójkątów foreach (trójkąt item in figury) { trójkąt Projected, Translated, RotZX, RotZ, Viewed; RotZ = new trójkąt(new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0)); RotZX = new trójkąt(new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0)); Viewed = new trójkąt(new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0)); MatrixMnożenia(MRotZ, item, RotZ); MatrixMnożenia(MRotX, RotZ, RotZX); //przyblizenie zeby widzeć fugurę Translated = RotZX; TranslatedZ(Translated, RotZX); Projected = new trójkąt(new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0), new Vector4(0, 0, 0, 0)); //uleprzenie widoka figury aby figury nie były przezroczyste Vector4 norm, linefirst, linesecond; linefirst = new Vector4(0, 0, 0, 0); linesecond = new Vector4(0, 0, 0, 0); linefirst.X = Translated.tlist[1].X - Translated.tlist[0].X; linefirst.Y = Translated.tlist[1].Y - Translated.tlist[0].Y; linefirst.Z = Translated.tlist[1].Z - Translated.tlist[0].Z; linesecond.X = Translated.tlist[2].X - Translated.tlist[0].X; linesecond.Y = Translated.tlist[2].Y - Translated.tlist[0].Y; linesecond.Z = Translated.tlist[2].Z - Translated.tlist[0].Z; norm = functions.VectorCrossProd(linefirst, linesecond); norm = functions.VNormalise(norm); float scalar = norm.X * (Translated.tlist[0].X - Camera.X) + norm.Y * (Translated.tlist[0].Y - Camera.Y) + norm.Z * (Translated.tlist[0].Z - Camera.Z); if (scalar < 0.0f) { //pozycja swiatła Vector4 light = new Vector4(0.0f, -1.0f, -1.0f, 1.0f); light = functions.VNormalise(light); float m = norm.X * light.X + norm.Y * light.Y + norm.Z * light.Z; MatrixMnożenia(mView, Translated, Viewed); int ClippedT = 0; trójkąt[] cliped = new trójkąt[2] { new trójkąt(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1)), new trójkąt(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1)) };; Vector4 p_p = new Vector4(0.0f, 0.0f, 0.1f, 1.0f); Vector4 p_n = new Vector4(0.0f, 0.0f, 1.0f, 1.0f); ClippedT = functions.TClipPlane(p_p, p_n, Viewed, ref cliped[0], ref cliped[1]); for (int i = 0; i < ClippedT; i++) { MatrixMnożenia(matrixProj, cliped[i], Projected); Scale(Projected); Projected.m = m; Rastr.Add(Projected); } } } Rastr.Sort(); foreach (var tri in Rastr) { FillFigure(tri, bm); } pb.Image = bm; pb.Refresh(); }
public int TClipPlane(Vector4 plane_p, Vector4 plane_n, trójkąt in_tri, ref trójkąt out_tri1, ref trójkąt out_tri2) { plane_n = VNormalise(plane_n); Vector4[] insidePoints = new Vector4[3]; Vector4[] outsidePoints = new Vector4[3]; int nInsidePointCount = 0; int noutsidePointsCount = 0; float d0 = distans(in_tri.tlist[0], plane_n, plane_p); float d1 = distans(in_tri.tlist[1], plane_n, plane_p); float d2 = distans(in_tri.tlist[2], plane_n, plane_p); if (d0 >= 0) { insidePoints[nInsidePointCount++] = in_tri.tlist[0]; } else { outsidePoints[noutsidePointsCount++] = in_tri.tlist[0]; } if (d1 >= 0) { insidePoints[nInsidePointCount++] = in_tri.tlist[1]; } else { outsidePoints[noutsidePointsCount++] = in_tri.tlist[1]; } if (d2 >= 0) { insidePoints[nInsidePointCount++] = in_tri.tlist[2]; } else { outsidePoints[noutsidePointsCount++] = in_tri.tlist[2]; } if (nInsidePointCount == 0) { return(0); } if (nInsidePointCount == 3) { out_tri1 = in_tri; return(1); } if (nInsidePointCount == 1 && noutsidePointsCount == 2) { out_tri1.tlist[0] = insidePoints[0]; out_tri1.tlist[1] = V_IntersectPlane(plane_p, plane_n, insidePoints[0], outsidePoints[0]); out_tri1.tlist[2] = V_IntersectPlane(plane_p, plane_n, insidePoints[0], outsidePoints[1]); return(1); } if (nInsidePointCount == 2 && noutsidePointsCount == 1) { out_tri1.tlist[0] = insidePoints[0]; out_tri1.tlist[1] = insidePoints[1]; out_tri1.tlist[2] = V_IntersectPlane(plane_p, plane_n, insidePoints[0], outsidePoints[0]); out_tri2.tlist[0] = insidePoints[1]; out_tri2.tlist[1] = out_tri1.tlist[2]; out_tri2.tlist[2] = V_IntersectPlane(plane_p, plane_n, insidePoints[1], outsidePoints[0]); return(2); } return(0); }