private void DrawLine(FastBitmap bitmap, double[,] buffer, Point3D start, Point3D end, Color color) { double dx = end.X - start.X; double dy = end.Y - start.Y; if (Math.Abs(dx) > Math.Abs(dy)) { if (dx < 0) { MathHelp.Swap(ref start, ref end); } double[] ys = MathHelp.Interpolate(start.X, start.Y, end.X, end.Y); double[] zs = MathHelp.Interpolate(start.X, start.Z, end.X, end.Z); Parallel.For((int)start.X, (int)end.X, x => { int y = (int)ys[(int)(x - start.X)]; double z = zs[(int)(x - start.X)]; if (IsOnImage((int)x, y) && buffer[(int)x, y] >= z) { buffer[(int)x, y] = z; bitmap.SetPixel((int)x, y, color); } }); } else { if (dy < 0) { MathHelp.Swap(ref start, ref end); } double[] xs = MathHelp.Interpolate(start.Y, start.X, end.Y, end.X); double[] zs = MathHelp.Interpolate(start.Y, start.Z, end.Y, end.Z); Parallel.For((int)start.Y, (int)end.Y, y => { int x = (int)xs[(int)(y - start.Y)]; double z = zs[(int)(y - start.Y)]; if (IsOnImage(x, (int)y) && buffer[x, (int)y] >= z) { buffer[x, (int)y] = z; bitmap.SetPixel(x, (int)y, color); } }); } }
private void Triangle(Vector3D p0, Vector3D p1, Vector3D p2, Color color, FastBitmap bitmap, double[,] buffer) { if (p0.Y != p1.Y || p0.Y != p2.Y) { if (p0.Y > p1.Y) { MathHelp.Swap(ref p0, ref p1); } if (p0.Y > p2.Y) { MathHelp.Swap(ref p0, ref p2); } if (p1.Y > p2.Y) { MathHelp.Swap(ref p1, ref p2); } int totalHeight = (int)Math.Round(p2.Y - p0.Y); Parallel.For(0, totalHeight - 1, i => { bool secondHalf = i > p1.Y - p0.Y || p1.Y == p0.Y; int segmentHeight = (int)Math.Round(secondHalf ? p2.Y - p1.Y : p1.Y - p0.Y); double alpha = (double)i / totalHeight; double beta = (i - (secondHalf ? p1.Y - p0.Y : 0.0)) / segmentHeight; Vector3D a = p0 + (p2 - p0) * alpha; Vector3D b = (secondHalf ? p1 + (p2 - p1) * beta : p0 + (p1 - p0) * beta); if (a.X > b.X) { MathHelp.Swap(ref a, ref b); } for (int j = (int)Math.Round(a.X); j <= (int)Math.Round(b.X); ++j) { double scale = (a.X == b.X) ? 1 : (j - a.X) / (b.X - a.X); Vector3D p = a + (b - a) * scale; int x = (int)Math.Round(p.X); int y = (int)Math.Round(p.Y); if (IsOnImage(x, y) && buffer[x, y] >= p.Z) { buffer[x, y] = p.Z; bitmap.SetPixel(x, y, color); } } }); } }