public partial class Form1 : Form
{
Double Phi, Psi;
const int MAXX = 800;// размерность
const int MAXY = 480;// размерность
int[] YMax = new int[MAXX];//?
int[] YMin = new int[MAXX];//массивы для определения цвета прямой
Boolean flag = false;
public Form1()
{
InitializeComponent();
Psi = 3;
Phi = 350;
tPSI.Value = 3;
tPHI.Value = 350;
this.pictureBox1.Paint += new PaintEventHandler(this.picPaint);
}
public void picPaint(object sender, PaintEventArgs e)//?(2 флага одинаковых) можно выкинуть
{
if(flag)
PlotSurface(-5, -5, 5, 5, -0.2, 0.3, 1000, 100, 20, 380, e.Graphics);
if (!flag)
PlotSurface(-5, -5, 5, 5, -0.2, 0.3, 1000, 100, 20, 380, e.Graphics);
}
public void PlotSurface(double x1, double y1, double x2, double y2, double fmin, double fmax, int n1, int n2, int Dx, int Dy, Graphics g)
{
Point[] CurLine = new Point[n1];//массив текущих линий
double phi = Phi * Math.PI / 180;
double psi = Psi * Math.PI / 180;
double sin_phi = Math.Sin(phi);
double sin_psi = Math.Sin(psi);
double cos_phi = Math.Cos(phi);
double cos_psi = Math.Cos(psi);
double[] e1 = new double[3] { cos_phi, sin_phi, 0 };//вектора проецирования
double[] e2 = new double[3] { sin_psi * sin_phi, -sin_psi * cos_phi, cos_psi };// и этот тоже
double x, y;
double hx = (x2 - x1) / n1;//вроде шаг, точно не помню
double hy = (y2 - y1) / n2;//
double xmin = (e1[0] >= 0 ? x1 : x2) * e1[0] + (e1[1] >= 0 ? y1 : y2) * e1[1];//
double xmax = (e1[0] >= 0 ? x2 : x1) * e1[0] + (e1[1] >= 0 ? y2 : y1) * e1[1];
double ymin = (e2[0] >= 0 ? x1 : x2) * e2[0] + (e2[1] >= 0 ? y1 : y2) * e2[1];
double ymax = (e2[0] >= 0 ? x2 : x1) * e2[0] + (e2[1] >= 0 ? y2 : y1) * e2[1];
int i, j;
if (e2[2] >= 0)//условие, которым определяем параметры ymax, ymin, не вникал в его смысл
{
ymin += fmin * e2[2];
ymax += fmax * e2[2];
}
else
{
ymin += fmax * e2[2];
ymax += fmin * e2[2];
}
double ax = Dx - (MAXX - 40) * xmin / (xmax - xmin);//у нас есть ограничивающий прямоугольник
double bx = (MAXX - 40) / (xmax - xmin);//с помощью этой конструкции
double ay = Dy - (MAXY - 80) * ymin / (ymax - ymin);// считаем точки внутри этого
double by = -(MAXY - 80) / (ymax - ymin);//прямоугольника
for (i = 0; i < MAXX; i++)//зануляем массивы
YMin[i] = YMax[i] = 0;
for (i = n2 - 1; i > -1; i--)//бегаем по всем точкам и получаем точки для линии
{
for (j = 0; j < n1; j++)
{
x = x1 + j * hx;
y = y1 + i * hy;
CurLine[j].X = (int)(ax + bx * (x * e1[0] + y * e1[1]));
CurLine[j].Y = (int)(ay + by * (x * e2[0] + y * e2[1] + f(x, y) * e2[2]));
}
for (j = 0; j < n1 - 1; j++)//закрашиваем
DrawLine(CurLine[j], CurLine[j + 1], g);
///g.DrawLine(new Pen(Color.Black), CurLine[j], CurLine[j + 1]);
}
}
double f(double x, double y)//тут задаем нашу функцию двух переменных, которая будет рисоваться
{
double r = Math.Sin(x * x / 225 + y * y / 64) + 1;
return Math.Sqrt(r);
}
private void tPSI_Scroll(object sender, EventArgs e)
{
Psi = tPSI.Value;
flag = true;
pictureBox1.Invalidate();
}
private void tPHI_Scroll(object sender, EventArgs e)
{
Phi = tPHI.Value;
flag = true;
pictureBox1.Invalidate();
}
private void button1_Click_1(object sender, EventArgs e)
{
tPHI.Value = 320;
tPSI.Value = 3;
flag = false;
pictureBox1.Invalidate();
}
private void DrawLine(Point p1, Point p2, Graphics g)
{
Color UpColor = Color.Red;
Color DownColor = Color.Green;
int dx = Math.Abs(p2.X - p1.X);//шаг - да
int dy = Math.Abs(p2.Y - p1.Y);
int sx = p2.X >= p1.X ? 1 : -1;// с четвертями замут, который был в Брезенхейме
int sy = p2.Y >= p1.Y ? 1 : -1;
if (dy <= dx)// проверка на дурака
{
int d = -dx;
int d1 = dy << 1;// алгоритм Брезенхейма
int d2 = (dy - dx) << 1;//
for (int x = p1.X, y = p1.Y, i = 0; i <= dx; i++, x += sx)//то же самое
{
//во всех ивах просто проверяем с какой стороны смотрим на кривую, снизу или сверху и все
if (YMin[x] == 0)//
{
g.DrawRectangle(new Pen(UpColor), x, y, 1, 1);
YMin[x] = YMax[x] = y;
}
else if (y < YMin[x])//?
{
g.DrawRectangle(new Pen(UpColor), x, y, 1, 1);
YMin[x] = y;
}
else if (y > YMax[x])//?
{
g.DrawRectangle(new Pen(DownColor), x, y, 1, 1);
YMax[x] = y;
}
if (d > 0)//тоже часть алгоритма Брезенхейма
{
d += d2;
y += sy;
}
else d += d1;//?
}
}
else
{
int d = -dy;
int d1 = dx << 1;
int d2 = (dx - dy) << 1;
int m1 = YMin[p1.X];//?
int m2 = YMax[p1.X];//?
for (int x = p1.X, y = p1.Y, i = 0; i <= dy; i++, y += sy)//?
{
if (YMin[x] == 0)//что рисуем?
//В названии метода что написано? DrawRectangle, рисуем кубик, из кубиков собираем линию
{
g.DrawRectangle(new Pen(UpColor), x, y, 1, 1);
YMin[x] = YMax[x] = y;
}
else if (y < m1)//?
{
g.DrawRectangle(new Pen(UpColor), x, y, 1, 1);
if (y < YMin[x])
YMin[x] = y;
}
else if (y > m2)//?
{
g.DrawRectangle(new Pen(DownColor), x, y, 1, 1);
if (y > YMax[x])
YMax[x] = y;
}
if (d > 0)//?
{
d += d2;
x += sx;
m1 = YMin[x]; m2 = YMax[x];
}
else d += d1;
}
}
}
}
}