Компьютерная графика средствами Windows Forms
Двумерная графика: понятие и принципы формирования, правила преобразования координат. Сущность и работа с методом сканирующей строки. Параллельная и центральная проекция: сравнительная характеристика, главные условия и возможности использования.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 11.04.2015 |
Размер файла | 194,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
Введение
двумерный графика проекция координата
Существует немало языков программирования, но лишь немногие из них действительно хороши. Хороший язык программирования должен быть одновременно эффективным и гибким, а его синтаксис - кратким, но ясным. Он должен облегчать создание правильного кода, не мешая делать это, а также поддерживать самые современные возможности программирования, но не ультрамодные тенденции, заводящие в тупик. И наконец, хороший язык программирования должен обладать еще одним, едва уловимым качеством: вызывать у нас такое ощущение, будто мы находимся в своей стихии, когда пользуемся им. Именно таким языком и является С# [1].
Данная работа посвящена изучению некоторых разделов интерактивной компьютерной графики средствами C#.
1. Двумерная графика
Задача: Написать программу, которая строит график функции на отрезке [a, b], заданной явно. Подобрать отрезок [a, b], который содержит только одну точку разрыва [2].
Решение:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
using System. Drawing. Drawing2D;
namespace WindowsFormsApplication5
{
public partial class Form1: Form
{
public Form1 ()
{
InitializeComponent();
}
protected override void OnPaint (PaintEventArgs e)
{
base. OnPaint(e);
Graphics g = e. Graphics;
float xmin, xmax, ymin, ymax, x, y, h;
int r = 3;
double eps = 0.001;
xmin = 1; xmax = 6;
h = (xmax - xmin) / 500;
ymin = F(xmin);
ymax = ymin;
x = xmin + h;
for (x = xmin; x < r-eps; x = x + h)
{
y = F(x);
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
for (x = r + h; x <= xmax; x = x + h)
{
y = F(x);
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
float dx = (xmax - xmin) * 0.03f;
float dy = (ymax - ymin) * 0.03f;
float ax = ClientSize. Width / (xmax - xmin + 2 * dx);
float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);
float bx = - ax * (xmin - dx);
float by = - ay * (ymax + dy);
g. Transform = new Matrix (ax, 0, 0, ay, bx, by);
float hf, wf, a, b, c, d;
float asm = (xmax - xmin) / (ymax - ymin);
float asf = (float) ClientSize. Width / (float) ClientSize. Height;
if (asm > asf)
{
wf = ClientSize. Width;
hf = (ymax - ymin) * wf / (xmax - xmin);
a = 0;
b = (ClientSize. Height - hf) / 2;
c = ClientSize. Width;
d = (ClientSize. Height + hf) / 2;
}
else
{
hf = ClientSize. Height;
wf = (xmax - xmin) * hf / (ymax - ymin);
a = (ClientSize. Width - wf) / 2;
b = 0;
c = (ClientSize. Width + wf) / 2;
d = ClientSize. Height;
}
ax = (c - a) / (xmax - xmin + 2 * dx);
ay = (b - d) / (ymax - ymin + 2 * dy);
bx = a - ax * (xmin - dx);
by = b - ay * (ymax + dy);
float hline = (xmax - xmin) * 0.001f;
Pen blackPen = new Pen (Color. Black, hline);
Pen bluePen = new Pen (Color. Blue, hline);
x = xmin;
g. DrawLine (bluePen, xmin, 0, xmax, 0);
g. DrawLine (bluePen, 0, ymin, 0, ymax);
while (x <= r - h)
{
g. DrawLine (blackPen, x, F(x), x + h, F (x + h));
x = x + h;
}
x = r + h;
while (x <= xmax)
{
g. DrawLine (blackPen, x, F(x), x + h, F (x + h));
x = x + h;
}
}
private float F (float x)
{
return x / (x * x - 9);
}
private void Form1_Resize (object sender, EventArgs e)
{
Invalidate();
}
}
}
Рисунок 1.1 Реализация программы, которая строит двумерный график функции, заданной явно, с одной точкой разрыва
Задача: Написать программу, которая строит график функции на отрезке [a, b], заданной параметрически.
Решение:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
using System. Drawing;
using System. Drawing. Drawing2D;
namespace WindowsFormsApplication1
{
public partial class Form1: Form
{
public Form1 ()
{
InitializeComponent();
}
protected override void OnPaint (PaintEventArgs e)
{
base. OnPaint(e);
Graphics g = e. Graphics;
float xmin, xmax, ymin, ymax, x, t, y, h;
float tmin = -5, tmax = 5;
xmin = F1 (tmin); xmax = F1 (tmax);
h = (tmax - tmin) / 500;
ymin = F2 (tmin);
ymax = ymin;
t = tmin + h;
for (t = tmin; t < tmax; t = t + h)
{
x = F1 (t);
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
y = F2 (t);
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
float dx = (xmax - xmin) * 0.03f;
float dy = (ymax - ymin) * 0.03f;
float ax = ClientSize. Width / (xmax - xmin + 2 * dx);
float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);
float bx = - ax * (xmin - dx);
float by = - ay * (ymax + dy);
float hf, wf, a, b, c, d;
float asm = (xmax - xmin) / (ymax - ymin);
float asf = (float) ClientSize. Width / (float) ClientSize. Height;
if (asm > asf)
{
wf = ClientSize. Width;
hf = (ymax - ymin) * wf / (xmax - xmin);
a = 0;
b = (ClientSize. Height - hf) / 2;
c = ClientSize. Width;
d = (ClientSize. Height + hf) / 2;
}
else
{
hf = ClientSize. Height;
wf = (xmax - xmin) * hf / (ymax - ymin);
a = (ClientSize. Width - wf) / 2;
b = 0;
c = (ClientSize. Width + wf) / 2;
d = ClientSize. Height;
}
ax = (c - a) / (xmax - xmin + 2 * dx);
ay = (b - d) / (ymax - ymin + 2 * dy);
bx = a - ax * (xmin - dx);
by = b - ay * (ymax + dy);
g. Transform = new Matrix (ax, 0, 0, ay, bx, by);
float hline = (xmax - xmin) * 0.001f;
Pen blackPen = new Pen (Color. Black, hline);
Pen bluePen = new Pen (Color. Blue, hline);
t = tmin;
g. DrawLine (bluePen, xmin, 0, xmax, 0);
g. DrawLine (bluePen, 0, ymin, 0, ymax);
while (t <= tmax)
{
g. DrawLine (blackPen, F1 (t), F2 (t), F1 (t + h), F2 (t + h));
t = t + h;
}
}
private float F1 (float x)
{
return (float) (6 * Math. Cos(x) + 2 * Math. Cos (6 * x));
}
private float F2 (float x)
{
return (float) (6 * Math. Sin(x) - 2 * Math. Sin (6 * x));
}
private void Form1_Resize (object sender, EventArgs e)
{
Invalidate();
}
}
}
Рисунок 1.2 Реализация программы, которая строит двумерный график функции, заданной параметрически
2. Преобразования двумерных координат
Задача: Написать программу, демонстрирующую преобразование двумерных координат (перенос, поворот и масштабирование). Вывести график функции до преобразования и после него в одном окне [2].
Решение:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
using System. Drawing;
using System. Drawing. Drawing2D;
namespace WindowsFormsApplication1
{
public partial class Form1: Form
{
public Form1 ()
{
InitializeComponent();
}
public float transX (float x, float y, float Alfa, float d, float s)
{
return (float) ((s * x * Math. Cos(Alfa) + s * y * Math. Sin(Alfa) + d));
}
public float transY (float x, float y, float Alfa, float d, float s)
{
return (float) (-s * x * Math. Sin(Alfa) + s * y * Math. Cos(Alfa) + d);
}
protected override void OnPaint (PaintEventArgs e)
{
base. OnPaint(e);
Graphics g = e. Graphics;
float fi, fimin, fimax, xmin, xmax, ymin, ymax, x, y, h, x2, y2;
float tx, ty, Alfa, s;
s = 2;
tx = 10; ty = 7; Alfa = (float) (Math.PI) / 6;
fimin = 0; fimax = (float) (4 * (Math.PI));
h = (fimax - fimin) / 100;
xmin = (float) (F(fimin) * Math. Cos(fimin));
ymin = (float) (F(fimin) * Math. Sin(fimin));
xmax = xmin;
ymax = ymin;
fi = fimin + h;
while (fi < fimax)
{
x = (float) (F(fi) * Math. Cos(fi));
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
y = (float) (F(fi) * Math. Sin(fi));
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
x2 = transX (x, y, Alfa, tx, s);
if (x2 < xmin) xmin = x2;
if (x2 > xmax) xmax = x2;
y2 = transY (x, y, Alfa, ty, s);
if (y2 < ymin) ymin = y2;
if (y2 > ymax) ymax = y2;
fi = fi + h;
}
float dx = (xmax - xmin) * 0.03f;
float dy = (ymax - ymin) * 0.03f;
float ax = ClientSize. Width / (xmax - xmin + 2 * dx);
float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);
float bx = - ax * (xmin - dx);
float by = - ay * (ymax + dy);
float hf, wf, a, b, c, d;
float asm = (xmax - xmin) / (ymax - ymin);
float asf = (float) ClientSize. Width / (float) ClientSize. Height;
if (asm > asf)
{
wf = ClientSize. Width;
hf = (ymax - ymin) * wf / (xmax - xmin);
a = 0;
b = (ClientSize. Height - hf) / 2;
c = ClientSize. Width;
d = (ClientSize. Height + hf) / 2;
}
else
{
hf = ClientSize. Height;
wf = (xmax - xmin) * hf / (ymax - ymin);
a = (ClientSize. Width - wf) / 2;
b = 0;
c = (ClientSize. Width + wf) / 2;
d = ClientSize. Height;
}
ax = (c - a) / (xmax - xmin + 2 * dx);
ay = (b - d) / (ymax - ymin + 2 * dy);
bx = a - ax * (xmin - dx);
by = b - ay * (ymax + dy);
g. Transform = new Matrix (ax, 0, 0, ay, bx, by);
float hline = (xmax - xmin) * 0.001f;
Pen blackPen = new Pen (Color. Black, hline);
Pen bluePen = new Pen (Color. Blue, hline);
g. DrawLine (bluePen, xmin, 0, xmax, 0);
g. DrawLine (bluePen, 0, ymin, 0, ymax);
fi = fimin;
while (fi <= fimax)
{
g. DrawLine (blackPen, (float) (F(fi) * Math. Cos(fi)), (float) (F(fi) * Math. Sin(fi)), (float) (F (fi + h) * Math. Cos (fi + h)), (float) (F (fi + h) * Math. Sin (fi + h)));
fi = fi + h;
}
fi = fimin;
while (fi <= fimax)
{
x = (float) (F(fi) * Math. Cos(fi));
y = (float) (F(fi) * Math. Sin(fi));
x2 = (float) (F (fi + h) * Math. Cos (fi + h));
y2 = (float) (F (fi + h) * Math. Sin (fi + h));
g. DrawLine (blackPen, transX (x, y, Alfa, tx, s), transY (x, y, Alfa, ty, s), transX (x2, y2, Alfa, tx, s), transY (x2, y2, Alfa, ty, s));
fi = fi + h;
}
}
private float F (float fi)
{
return 3 * (1 + (float) (Math. Cos(fi)));
}
private void Form1_Resize (object sender, EventArgs e)
{
Invalidate();
}
}
}
Рисунок 2.1 Реализация программы, демонстрирующей преобразование двумерных координат
3. Метод сканирующей строки
Задача: Разработать алгоритм и написать программу, демонстрирующую метод сканирующей строки для закрашивания треугольных областей [2].
Решение:
Класс:
using System;
using System. Collections. Generic;
using System. Linq;
using System. Text;
using System. Drawing;
using System. Drawing. Drawing2D;
using System. Collections;
namespace Laba3
{
class FillTriangle
{
public void Fill (Graphics g, int[] x, int[] y, int[] rgb)
{
int maxy, miny;
maxy = y[0];
miny = maxy;
if (y[1] > maxy) maxy = y[1];
if (y[2] > maxy) maxy = y[2];
if (y[1] < miny) miny = y[1];
if (y[2] < miny) miny = y[2];
float t;
ArrayList mas = new ArrayList();
Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));
for (int yt = miny; yt <= maxy; yt++)
{
mas. Clear();
if (y[0]!=y[1])
{
t = (float) (yt-y[1])/(float) (y[0] - y[1]);
if (t>=0 && t<=1)
mas. Insert (0, (int) (t*x[0] + (1-t)*x[1]));
}
{
t = (float) (yt-y[2])/(float) (y[1] - y[2]);
if (t>=0 && t<=1)
mas. Insert (0, (int) (t*x[1] + (1-t)*x[2]));
}
{
t = (float) (yt-y[2])/(float) (y[0] - y[2]);
if (t>=0 && t<=1)
mas. Insert (0, (int) (t*x[0] + (1-t)*x[2]));
}
g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);
if (mas. Count == 3)
{
g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);
}
}
}
}
}
Форма:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
using System. Drawing;
using System. Drawing. Drawing2D;
namespace Laba3
{
public partial class Form1: Form
{
private int k = 0;
private int[] x = new int[3];
private int[] y = new int[3];
private int[] rgb = new int[3];
public Form1 ()
{
InitializeComponent();
}
private void Form1_MouseDown (object sender, MouseEventArgs e)
{
if (k <= 2)
{
x[k] = e.X;
y[k] = e.Y;
if (k == 2)
{
rgb[0] = 255;
rgb[2] = 0;
rgb[2] = 0;
Graphics g = Graphics. FromHwnd (this. Handle);
FillTriangle f = new FillTriangle();
f. Fill (g, x, y, rgb);
g. Dispose();
}
k++;
}
else
return;
}
}
}
Рисунок 3.1 Реализация программы, демонстрирующей метод сканирующей строки для закрашивания треугольных областей
4. Параллельная проекция
Задача: Написать программу, которая строит на экране изображение выпуклого трехмерного тела при параллельной проекции. Удалить невидимые грани. Видимые грани закрасить оттенками серого цвета в зависимости от расположения соответствующей грани и источника света. Для закрашивания граней использовать метод сканирующей строки [2].
Решение:
Класс:
using System;
using System. Collections. Generic;
using System. Linq;
using System. Text;
using System. Drawing;
using System. Collections;
namespace Triangle
{
class FillTriangle
{
public void Fill (Graphics g, int[] x, int[] y, int[] rgb)
{
int maxy, miny;
ArrayList mas = new ArrayList();
float a;
Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));
if (Math. Abs((x[1] - x[0]) * (y[2] - y[0]) - (x[2] - x[0]) * (y[1] - y[0])) <= 0.001)
{
g. DrawLine (myPen, x[0], y[0], x[1], y[1]);
g. DrawLine (myPen, x[1], y[1], x[2], y[2]);
return;
}
maxy = y[0];
miny = maxy;
for (int i = 1; i <= 2; i++)
{
if (y[i] > maxy) maxy = y[i];
if (y[i] < miny) miny = y[i];
}
for (int yt = miny; yt <= maxy; yt++)
{
mas. Clear();
if (y[0]!= y[1])
{
a = (float) (yt - y[1])/(float) (y[0] - y[1]);
if (a >= 0 && a <= 1)
{
mas. Insert (0, (int) (a * x[0] + (1 - a) * x[1]));
}
}
if (y[1]!= y[2])
{
a = (float) (yt - y[2]) / (float) (y[1] - y[2]);
if (a >= 0 && a <= 1)
{
mas. Insert (0, (int) (a * x[1] + (1 - a) * x[2]));
}
}
if (y[0]!= y[2])
{
a = (float) (yt - y[2]) / (float) (y[0] - y[2]);
if (a >= 0 && a <= 1)
{
mas. Insert (0, (int) (a * x[0] + (1 - a) * x[2]));
}
}
if (mas. Count == 3)
{
g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);
g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);
}
else
g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);
}
}
}
}
Форма:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
using System. Drawing. Drawing2D;
namespace Lab_4
{
public partial class Form1: Form
{
private double[] xv = {0, 2, 0, 0, 2, 0};
private double[] yv = {0, 0, 2, 0, 0, 2};
private double[] zv = {0, 0, 0, 2, 2, 2};
private double[] xpl = new double[6];
private double[] ypl = new double[6];
private int[] xfrm = new int[6];
private int[] yfrm = new int[6];
private int[,] gran1 = new int [3, 4];
private int[,] gran2 = new int [2, 3];
private double u1x, u1y, u1z, u2x, u2y, u2z, u3x, u3y, u3z;
private double rx, ry, rz;
private double ax, ay, az;
private double sx, sy, sz;
private double r;
private double a, b, c, d;
public Form1 ()
{
InitializeComponent();
}
private void Form1_Load (object sender, EventArgs e)
{
rx = 10; ry = 5; rz = 5;
ax = 1; ay = 1; az = 1;
sx = -5; sy = 1; sz = 5;
r = Math. Sqrt(3);
u3x = ax - rx; u3y = ay - ry; u3z = az - rz;
double t = Math. Sqrt (u3x * u3x + u3y * u3y + u3z * u3z);
u3x = u3x / t; u3y = u3y / t; u3z = u3z / t;
u1x = u3y; u1y = - u3x; u1z = 0;
t = Math. Sqrt (u1x * u1x + u1y * u1y + u1z * u1z);
u1x = u1x / t; u1y = u1y / t; u1z = u1z / t;
u2x = u1y * u3z - u3y * u1z; u2y = u3x * u1z - u1x * u3z; u2z = u1x * u3y - u3x * u1y;
t = Math. Sqrt (u2x * u2x + u2y * u2y + u2z * u2z);
u2x = u2x / t; u2y = u2y / t; u2z = u2z / t;
gran1 [1, 0] = 0; gran1 [1, 1] = 1; gran1 [1, 2] = 4; gran1 [1, 3] = 3;
gran1 [0, 0] = 0; gran1 [0, 1] = 3; gran1 [0, 2] = 5; gran1 [0, 3] = 2;
gran1 [2, 0] = 1; gran1 [2, 1] = 2; gran1 [2, 2] = 5; gran1 [2, 3] = 4;
gran2 [0, 0] = 0; gran2 [0, 1] = 2; gran2 [0, 2] = 1;
gran2 [1, 0] = 3; gran2 [1, 1] = 4; gran2 [1, 2] = 5;
for (int i = 0; i < xv. Length; i++)
{
xpl[i] = px (xv[i], yv[i], zv[i]);
ypl[i] = py (xv[i], yv[i], zv[i]);
}
Ini();
}
private double px (double x, double y, double z)
{
return ((x - rx) * u1x + (y - ry) * u1y + (z - rz) * u1z);
}
private double py (double x, double y, double z)
{
return ((x - rx) * u2x + (y - ry) * u2y + (z - rz) * u2z);
}
private void Ini()
{
double wp, hp;
if (ClientSize. Width >= ClientSize. Height)
{
wp = 2 * r * ClientSize. Width / ClientSize. Height; hp = 2 * r;
}
else
{
wp = 2 * r; hp = 2 * r * ClientSize. Height / ClientSize. Width;
}
a = ClientSize. Width / wp;
b = ClientSize. Width / 2;
c = - ClientSize. Height / hp;
d = ClientSize. Height / 2;
}
protected override void OnPaint (PaintEventArgs e)
{
base. OnPaint(e);
Graphics g=e. Graphics;
g. Clear (Color. White);
for (int i=0; i<xv. Length; i++)
{
xfrm[i]=fx (xpl[i]);
yfrm[i]=fy (ypl[i]);
}
double bx, by, bz, cx, cy, cz, nx, ny, nz;
int[] rgb=new int[3];
int[] x=new int[3]; int[] y=new int[3];
double cosfi;
Triangle. FillTriangle myFill=new Triangle. FillTriangle();
for (int i=0; i<=2; i++)
{
bx=xv [gran1 [i, 1]] - xv [gran1 [i, 0]];
by=yv [gran1 [i, 1]] - yv [gran1 [i, 0]];
bz=zv [gran1 [i, 1]] - zv [gran1 [i, 0]];
cx=xv [gran1 [i, 2]] - xv [gran1 [i, 0]];
cy=yv [gran1 [i, 2]] - yv [gran1 [i, 0]];
cz=zv [gran1 [i, 2]] - zv [gran1 [i, 0]];
nx=by*cz-bz*cy;
ny=bz*cx-bx*cz;
nz=bx*cy-by*cx;
if (nx*u3x+ny*u3y+nz*u3z>0)
{
bx=xv [gran1 [i, 0]]; by=yv [gran1 [i, 0]]; bz=zv [gran1 [i, 0]];
for (int j=1; j<=3; j++)
{
bx+=xv [gran1 [i, j]]; by+=yv [gran1 [i, j]]; bz+=zv [gran1 [i, j]];
}
bx=bx/4; by=by/4; bz=bz/4;
cx=bx-sx; cy=by-sy; cz=bz-sz;
cosfi=(nx*cx+ny*cy+nz*cz)/ (Math. Sqrt (nx*nx+ny*ny+nz*nz)*Math. Sqrt (cx*cx+cy*cy+cz*cz));
rgb[0]=(int) (-255*cosfi/2+255/2);
rgb[1]=rgb[0]; rgb[2]=rgb[0];
x[0]=xfrm [gran1 [i, 0]]; y[0]=yfrm [gran1 [i, 0]];
x[1]=xfrm [gran1 [i, 1]]; y[1]=yfrm [gran1 [i, 1]];
x[2]=xfrm [gran1 [i, 2]]; y[2]=yfrm [gran1 [i, 2]];
myFill. Fill (g, x, y, rgb);
x[0]=xfrm [gran1 [i, 0]]; y[0]=yfrm [gran1 [i, 0]];
x[1]=xfrm [gran1 [i, 2]]; y[1]=yfrm [gran1 [i, 2]];
x[2]=xfrm [gran1 [i, 3]]; y[2]=yfrm [gran1 [i, 3]];
myFill. Fill (g, x, y, rgb);
}
}
for (int i = 0; i <= 1; i++)
{
bx = xv [gran2 [i, 1]] - xv [gran2 [i, 0]];
by = yv [gran2 [i, 1]] - yv [gran2 [i, 0]];
bz = zv [gran2 [i, 1]] - zv [gran2 [i, 0]];
cx = xv [gran2 [i, 2]] - xv [gran2 [i, 0]];
cy = yv [gran2 [i, 2]] - yv [gran2 [i, 0]];
cz = zv [gran2 [i, 2]] - zv [gran2 [i, 0]];
nx = by * cz - bz * cy;
ny = bz * cx - bx * cz;
nz = bx * cy - by * cx;
if (nx * u3x + ny * u3y + nz * u3z > 0)
{
bx = xv [gran2 [i, 0]]; by = yv [gran2 [i, 0]]; bz = zv [gran2 [i, 0]];
for (int j = 1; j <= 2; j++)
{
bx += xv [gran2 [i, j]]; by += yv [gran2 [i, j]]; bz += zv [gran2 [i, j]];
}
bx = bx / 3; by = by / 3; bz = bz / 3;
cx = bx - sx; cy = by - sy; cz = bz - sz;
cosfi = (nx * cx + ny * cy + nz * cz) / (Math. Sqrt (nx * nx + ny * ny + nz * nz) * Math. Sqrt (cx * cx + cy * cy + cz * cz));
rgb[0] = (int) (-255 * cosfi/2+255/2);
rgb[1] = rgb[0]; rgb[2] = rgb[0];
x[0] = xfrm [gran2 [i, 0]]; y[0] = yfrm [gran2 [i, 0]];
x[1] = xfrm [gran2 [i, 1]]; y[1] = yfrm [gran2 [i, 1]];
x[2] = xfrm [gran2 [i, 2]]; y[2] = yfrm [gran2 [i, 2]];
myFill. Fill (g, x, y, rgb);
x[0] = xfrm [gran2 [i, 0]]; y[0] = yfrm [gran2 [i, 0]];
x[1] = xfrm [gran2 [i, 1]]; y[1] = yfrm [gran2 [i, 1]];
x[2] = xfrm [gran2 [i, 2]]; y[2] = yfrm [gran2 [i, 2]];
myFill. Fill (g, x, y, rgb);
}
}
}
private int fx (double x)
{
return(int) (a*x+b);
}
private int fy (double y)
{
return(int) (c*y+d);
}
private void Form1_Resize (object sender, EventArgs e)
{
Ini();
Invalidate();
}
}
}
Рисунок 4.1 Реализация программы, которая строит на экране изображение выпуклого трехмерного тела при параллельной проекции
5. Центральная проекция
Задача: Написать программу, которая строит на экране изображение выпуклого трехмерного тела при центральной проекции. Удалить невидимые грани. Видимые грани закрасить оттенками серого цвета в зависимости от расположения соответствующей грани и источника света. Для закрашивания граней использовать метод сканирующей строки [2].
Решение:
Класс:
using System;
using System. Collections. Generic;
using System. Linq;
using System. Text;
using System. Drawing;
using System. Collections;
namespace WindowsFormsApplication1
{
class FillTriangle
{
public void Fill (Graphics g, int[] x, int[] y, int[] rgb)
{
int maxy, miny;
ArrayList mas = new ArrayList();
float a; // Параметр альфа
miny = y[0]; maxy = miny;
for (int i = 1; i < 3; i++)
{
if (y[i] > maxy) maxy = y[i];
if (y[i] < miny) miny = y[i];
}
Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));
for (int yt = miny; yt < maxy; yt++)
{
mas. Clear();
if (y[0]!= y[1])
{
a = (float) (yt-y[1]) / (float) (y[0] - y[1]);
if (a>=0&&a<=1)
mas. Insert (0, (int) (a*x[0]+(1-a)*x[1]));
}
if (y[0]!= y[2])
{
a = (float) (yt - y[2]) / (float) (y[0] - y[2]);
if (a >= 0 && a <= 1)
mas. Insert (0, (int) (a * x[0] + (1 - a) * x[2]));
}
if (y[1]!= y[2])
{
a = (float) (yt - y[2]) / (float) (y[1] - y[2]);
if (a >= 0 && a <= 1)
mas. Insert (0, (int) (a * x[1] + (1 - a) * x[2]));
}
if (mas. Count == 3)
g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);
g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);
}
}
}
}
Форма:
using System;
using System. Collections. Generic;
using System. ComponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
namespace WindowsFormsApplication1
{
public partial class Form1: Form
{
public Form1 ()
{
InitializeComponent();
}
double[] xv = {0, 0, 30, 30, 15, 15};
double[] yv = {0, -30, -30, 0, -15, -15};
double[] zv = {0, 0, 0, 0, 30, -30};
double[] xpl = new double[6];
double[] ypl = new double[6];
int[] xfrm = new int[6];
int[] yfrm = new int[6];
int[,] gran = new int [8, 3];
double u1x, u1y, u1z, u2x, u2y, u2z, u3x, u3y, u3z;
double rx, ry, rz, ax, ay, az, sx, sy, sz;
double r1, r2, a, b, c, d, fd, rd, gx, gy, gz;
private void Form1_Load (object sender, EventArgs e)
{
ax = 15; ay = -15; az = 0;
fd = 20;
sx = 90; sy = -60; sz = 50;
gx = 100; gy = 30; gz = 20;
r1 = 35;
u3x = ax - gx; u3y = ay - gy; u3z = az - gz;
double m = Math. Sqrt (u3x * u3x + u3y * u3y + u3z * u3z);
u3x = u3x / m; u3y = u3y / m; u3z = u3z / m;
u1x = u3y; u1y = - u3x; u1z = 0;
m = Math. Sqrt (u1x * u1x + u1y * u1y + u1z * u1z);
u1x = u1x / m; u1y = u1y / m; u1z = u1z / m;
u2x = - u3y * u1z + u1y * u3z;
u2y = - u1x * u3z + u3x * u1z;
u2z = - u3x * u1y + u1x * u3y;
m = Math. Sqrt (u2x * u2x + u2y * u2y + u2z * u2z);
u2x = u2x / m; u2y = u2y / m; u2z = u2z / m;
rx = gx + u3x * fd;
ry = gy + u3y * fd;
rz = gz + u3z * fd;
rd=Math. Sqrt (Math. Pow (rx-ax, 2)+Math. Pow (ry-ay, 2)+Math. Pow (rz-az, 2));
r2= r1*fd/(rd+fd);
gran [0, 0] = 1; gran [0, 1] = 4; gran [0, 2] = 0;
gran [1, 0] = 1; gran [1, 1] = 2; gran [1, 2] = 4;
gran [2, 0] = 2; gran [2, 1] = 3; gran [2, 2] = 4;
gran [3, 0] = 3; gran [3, 1] = 0; gran [3, 2] = 4;
gran [4, 0] = 5; gran [4, 1] = 1; gran [4, 2] = 0;
gran [5, 0] = 1; gran [5, 1] = 5; gran [5, 2] = 2;
gran [6, 0] = 5; gran [6, 1] = 3; gran [6, 2] = 2;
gran [7, 0] = 5; gran [7, 1] = 0; gran [7, 2] = 3;
for (int i = 0; i < 6; i++)
{
xpl[i] = px (xv[i], yv[i], zv[i]);
ypl[i] = py (xv[i], yv[i], zv[i]);
}
Ini();
}
private double px (double x, double y, double z)
{
double sc1 = ((x - rx) * u1x + (y - ry) * u1y + (z - rz) * u1z);
double sc2 = ((x - rx) * u3x + (y - ry) * u3y + (z - rz) * u3z);
return fd * sc1 / (sc2 + fd);
}
private double py (double x, double y, double z)
{
double sc1 = ((x - rx) * u2x + (y - ry) * u2y + (z - rz) * u2z);
double sc2 = ((x - rx) * u3x + (y - ry) * u3y + (z - rz) * u3z);
return fd * sc1 / (sc2 + fd);
}
private void Ini()
{
double wp, hp;
if (ClientSize. Width >= ClientSize. Height)
{
wp = 2 * r2 * ClientSize. Width / ClientSize. Height;
hp = 2 * r2;
}
else
{
wp = 2 * r2;
hp = 2 * r2 * ClientSize. Height / ClientSize. Width;
}
a = ClientSize. Width / wp;
b = ClientSize. Width / 2;
c = - ClientSize. Height / hp;
d = ClientSize. Height / 2;
}
private int fx (double x)
{
return (int) (a * x + b);
}
private int fy (double y)
{
return (int) (c * y + d);
}
protected override void OnPaint (PaintEventArgs e)
{
base. OnPaint(e);
Graphics g = e. Graphics;
g. Clear (Color. White);
for (int i = 0; i < xv. Length; i++)
{
xfrm[i] = fx (xpl[i]);
yfrm[i] = fy (ypl[i]);
}
double bx, by, bz, cx, cy, cz, nx, ny, nz;
int[] rgb = new int[3];
double cosfi;
int[] x = new int [3];
int[] y = new int [3];
FillTriangle myFill = new FillTriangle();
for (int i = 0; i < 8; i++)
{
bx = xv [gran[i, 1]] - xv [gran[i, 0]];
by = yv [gran[i, 1]] - yv [gran[i, 0]];
bz = zv [gran[i, 1]] - zv [gran[i, 0]];
cx = xv [gran[i, 2]] - xv [gran[i, 0]];
cy = yv [gran[i, 2]] - yv [gran[i, 0]];
cz = zv [gran[i, 2]] - zv [gran[i, 0]];
nx = by * cz - bz * cy;
ny = bz * cx - bx * cz;
nz = bx * cy - by * cx;
bx = (xv [gran[i, 0]] + xv [gran[i, 1]] + xv [gran[i, 2]]) / 3;
by = (yv [gran[i, 0]] + yv [gran[i, 1]] + yv [gran[i, 2]]) / 3;
bz = (zv [gran[i, 0]] + zv [gran[i, 1]] + zv [gran[i, 2]]) / 3;
cx = bx - gx; cy = by - gy; cz = bz - gz;
if (nx * cx + ny * cy + nz * cz < 0)
{
cx = bx - sx; cy = by - sy; cz = bz - sz;
cosfi = (nx * cx + ny * cy + nz * cz) / (Math. Sqrt (nx * nx + ny * ny + nz * nz) * (Math. Sqrt (cx * cx + cy * cy + cz * cz)));
rgb[0] = (int) (-255 * cosfi / 2 + 255 / 2); //red
rgb[1] = rgb [0]; //green
rgb[2] = rgb[0]; //blue
x[0] = xfrm [gran[i, 0]]; y[0] = yfrm [gran[i, 0]];
x[1] = xfrm [gran[i, 1]]; y[1] = yfrm [gran[i, 1]];
x[2] = xfrm [gran[i, 2]]; y[2] = yfrm [gran[i, 2]];
myFill. Fill (g, x, y, rgb);
}
}
}
private void Form1_Resize (object sender, EventArgs e)
{
Ini();
Invalidate();
}
}
}
Рисунок 5.1 Реализация программы, которая строит на экране изображение выпуклого трехмерного тела при центральной проекции
Заключение
В работе были изучены некоторые разделы интерактивной графики средствами C# при помощи примеров. Данные задачи позволили хорошо рассмотреть самые главные аспекты программирования.
Благодаря своей способности быстро приспосабливаться к постоянно меняющимся потребностям в области программирования С# по-прежнему остается живым и новаторским языком. А следовательно, он представляет собой один из самых эффективных и богатых своими возможностями языков в современном программировании. Это язык, пренебречь которым не может позволить себе ни один программист. И эта книга призвана помочь вам овладеть им [3].
Список использованных источников
1 Шилдт, Г. Полное руководство С#4.0 / Г. Шилдт. - М.: Вильямс, 2011.
2 Мак-Дональд, М. WPF Windows Presentation Foundation в.NET 4.0 с примерами на C# 2010 для профессионалов / М. Мак-Дональд. - М.: Вильямс, 2011.
3 Порев, В. Компьютерная графика: учеб. Пособие / В. Порев. - БХВ-Петербург.: 2004.
Размещено на Allbest.ru
Подобные документы
Компьютерная графика как область информатики, занимающаяся проблемами получения различных изображений на компьютере. Области применения компьютерной графики. Двумерная графика: фрактальная, растровая и векторная. Особенности трёхмерной графики.
реферат [756,4 K], добавлен 05.12.2010Команды, используемые для построения графиков функций одной переменной (двумерная графика). Назначение и возможности команды plot (), расположенной в системной библиотеке Maple, ее операции и принцип работы. Порядок отображения графиков функций.
лабораторная работа [141,8 K], добавлен 15.07.2009Направления и виды компьютерной графики. Векторные и растровые изображения, их отличия. Фрактальная графика, основанная на математических вычислениях. Компьютерная графика в производстве, архитектуре, науке и медицине, искусстве, анимации и Web-дизайне.
реферат [428,8 K], добавлен 09.12.2013Виды графических компьютерных изображений, принципы их формирования и типы форматов. Пиксель как основной элемент экранного изображения. Основные проблемы при работе с растровой графикой. Сравнительная характеристика растровой и векторной графики.
презентация [521,5 K], добавлен 16.01.2012Компьютерная графика как одно из популярных направлений использования компьютера, ее виды и особенности применения. Порядок и способы создания цифровых изображений, средства и обработка. Программы САПР и их использование в инженерной деятельности.
реферат [19,1 K], добавлен 14.09.2009Компьютерная графика как инструмент для синтеза (создания) изображений. Характеристика векторного, растрового и фрактального типов представления изображений, трёхмерная графика. Интерфейс программы "Photoshop", пример работы по коррекции фотографий.
курсовая работа [4,5 M], добавлен 19.01.2011Основные виды компьютерной графики. Достоинства и недостатки векторной графики. Сущность понятия "коэффициент прямоугольности пикселей". Математическая основа фрактальной графики. Сущность понятий "фрактал", "фрактальная геометрия", "фрактальная графика".
контрольная работа [20,6 K], добавлен 13.07.2010Компьютерная графика и визуализация данных, методы и средства создания и обработки изображений с помощью программно-аппаратных вычислительных комплексов. Понятие виртуальности, примеры применения игровой графики: пространство, спрайты, воксели, полигоны.
реферат [29,0 K], добавлен 03.06.2010Компьютерная графика как раздел информационных технологий, в котором изучают вопросы получения графических изображений с помощью компьютера. Ее классификация и типы, сравнительная характеристика, признаки: растровая, векторная, фрактальная и трехмерная.
презентация [2,0 M], добавлен 04.04.2016Состав, структура, назначение и описание компонентов электронного учебно-методического комплекса "Компьютерная графика". Формы реализации и требования к оформлению. Анализ рынка педагогических программных средств по обучению компьютерной графике.
курсовая работа [572,0 K], добавлен 19.03.2015