using System using System Collections Generic using System Linq using

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
namespace MMCG_lab_8_9
{
class ZBuffer
{
private int sX, sY;
private double[] zbuffer;
private double[,] Zbuf;
private Color[,] ZColor;
private const double ph = 10 * Math.PI / 180;
private const double ps = 50 * Math.PI / 180;
private Point3D e1 = new Point3D(Math.Cos(ph), Math.Sin(ph), 0);
private Point3D e2 = new Point3D(-1 * Math.Sin(ph) * Math.Sin(ps), Math.Cos(ph) * Math.Sin(ps), Math.Sin(ps));
public ZBuffer(int WIDTH, int HEIGHT)
{
sX = WIDTH;
sY = HEIGHT;
zbuffer = new double[sX * sY];
for (int i = 0; i < sX * sY; i++)
zbuffer[i] = -32000;
Zbuf = new double[sX, sY];
ZColor = new Color[sX, sY];
for (int i = 0; i < sX; i++)
for (int j = 0; j < sY; j++)
Zbuf[i, j] = 32000;
}
public void Show(List<Triangle> t, Graphics g)
{
for (int i = 0; i < t.Count; i++)
ZBuffPart(t[i]);
//DrawTriangle(t[i], g, t[i].color);
for (int i = 0; i < sX; i++)
for (int j = 0; j < sY; j++)
g.DrawRectangle(new Pen(ZColor[i, j]), i, j, 1, 1);
}
private void ZBuffPart(Triangle t)
{
double u, v, du, dv;
int x, y;
Point3D R = new Point3D(0, 0, 0);
du = 0.007;
dv = 0.007;
for (u = 0; u <= 1.0; u += du)
for (v = 0; v <= 1.0 - u; v += dv)
{
R.X = t.A.X + u * (t.B.X - t.A.X) + v * (t.C.X - t.A.X);
R.Y = t.A.Y + u * (t.B.Y - t.A.Y) + v * (t.C.Y - t.A.Y);
R.Z = t.A.Z + u * (t.B.Z - t.A.Z) + v * (t.C.Z - t.A.Z);
x = (int)Math.Round(R.scal(e1));
y = (int)Math.Round(R.scal(e2));
if (Zbuf[x, y] > R.Z)
{
Zbuf[x, y] = R.Z;
ZColor[x, y] = t.color;
}
}
}
public void DrawTriangle(Triangle t, Graphics g, Color color)
{
if (t.A.Y == t.B.Y && t.A.Y == t.C.Y) return;
if (t.A.Y > t.B.Y) { Point3D tmp; tmp = t.A; t.A = t.B; t.B = tmp; }
if (t.A.Y > t.C.Y) { Point3D tmp; tmp = t.A; t.A = t.C; t.C = tmp; }
if (t.B.Y > t.C.Y) { Point3D tmp; tmp = t.B; t.B = t.C; t.C = tmp; }
int total_height = (int)Math.Round(t.C.Y - t.A.Y);
for (int i = 0; i < total_height; i++)
{
bool second_half = i > t.B.Y - t.A.Y || t.B.Y == t.A.Y;
int segment_height = second_half ? (int)Math.Round(t.C.Y - t.B.Y) : (int)Math.Round(t.B.Y - t.A.Y);
float alpha = (float)i / total_height;
//alpha = Math.Abs(alpha);
float beta = (float)(i - (second_half ? t.B.Y - t.A.Y : 0)) / segment_height;
//beta = Math.Abs(beta);
Point3D A = new Point3D(t.A.X + (t.C.X - t.A.X) * alpha,
t.A.Y + (t.C.Y - t.A.Y) * alpha,
t.A.Z + (t.C.Z - t.A.Z) * alpha);
Point3D B = second_half ? new Point3D(t.B.X + (t.C.X - t.B.X) * beta,
t.B.Y + (t.C.Y - t.B.Y) * beta,
t.B.Z + (t.C.Z - t.B.Z) * beta)
:
new Point3D(t.A.X + (t.B.X - t.A.X) * beta,
t.A.Y + (t.B.Y - t.A.Y) * beta,
t.A.Z + (t.B.Z - t.A.Z) * beta);
if (A.X > B.X) { Point3D tmp; tmp = A; A = B; B = tmp; }
for (int j = (int)(A.X); j <= (int)(B.X); j++)
{
float phi = B.X == A.X ? 1.0f : (float)(j - A.X) / (float)(B.X - A.X);
//phi = Math.Abs(phi);
Point3D P = new Point3D(A.X + (B.X - A.X) * phi,
A.Y + (B.Y - A.Y) * phi,
A.Z + (B.Z - A.Z) * phi);
int idx = (int)(Math.Round(P.X * sX + P.Y));
if (zbuffer[idx] < P.Z)
{
zbuffer[idx] = P.Z;
g.DrawRectangle(new Pen(color), (int)j, (int)Math.Round(t.A.Y + i), 1, 1);
}
}
}
}
}
}